accrete 0.0.143__py3-none-any.whl → 0.0.144__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/log/admin.py +1 -1
- accrete/contrib/system_mail/tasks.py +4 -5
- accrete/contrib/ui/__init__.py +15 -14
- accrete/contrib/ui/filter.py +22 -13
- accrete/contrib/ui/response.py +540 -0
- accrete/contrib/ui/static/css/accrete.css +69 -12
- accrete/contrib/ui/static/css/accrete.css.map +1 -1
- accrete/contrib/ui/static/css/accrete.scss +370 -300
- accrete/contrib/ui/templates/ui/content.html +0 -0
- accrete/contrib/ui/templates/ui/content_right.html +2 -2
- accrete/contrib/ui/templates/ui/detail.html +11 -0
- accrete/contrib/ui/templates/ui/filter/filter.html +5 -5
- accrete/contrib/ui/templates/ui/filter/query_tags.html +1 -1
- accrete/contrib/ui/templates/ui/layout.html +69 -64
- accrete/contrib/ui/templates/ui/list.html +21 -19
- accrete/contrib/ui/templates/ui/list_update.html +9 -3
- accrete/contrib/ui/templates/ui/message.html +1 -1
- accrete/contrib/ui/templates/ui/modal.html +41 -32
- accrete/contrib/ui/templates/ui/table_row_update.html +2 -2
- accrete/contrib/ui/templates/ui/templatetags/field.html +19 -6
- accrete/contrib/ui/templates/ui/widgets/model_search_select.html +7 -7
- accrete/contrib/ui/templates/ui/widgets/model_search_select_multi.html +3 -3
- accrete/contrib/ui/templatetags/ui.py +24 -2
- accrete/contrib/user/templates/user/password_forgotten.html +1 -0
- accrete/contrib/user/templates/user/user_preferences.html +43 -0
- accrete/contrib/user/views.py +36 -37
- accrete/migrations/0008_alter_member_access_groups_and_more.py +23 -0
- accrete/utils/__init__.py +1 -0
- accrete/utils/forms.py +11 -3
- accrete/utils/views.py +1 -2
- accrete/views.py +2 -3
- {accrete-0.0.143.dist-info → accrete-0.0.144.dist-info}/METADATA +2 -2
- {accrete-0.0.143.dist-info → accrete-0.0.144.dist-info}/RECORD +35 -33
- accrete/contrib/ui/context.py +0 -123
- accrete/contrib/ui/static/css/.sass-cache/15adf1eed05371361b08787c918a7f18fc15be79/accrete.scssc +0 -0
- accrete/contrib/ui/utils.py +0 -88
- accrete/contrib/user/templates/user/user_form.html +0 -58
- {accrete-0.0.143.dist-info → accrete-0.0.144.dist-info}/WHEEL +0 -0
- {accrete-0.0.143.dist-info → accrete-0.0.144.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
{#{% extends 'ui/layout.html' %}#}
|
2
|
+
{% load i18n %}
|
3
|
+
{% load partials %}
|
4
|
+
{% load ui %}
|
5
|
+
|
6
|
+
{% partialdef header %}
|
7
|
+
{% if not user.is_managed %}
|
8
|
+
<button class="button is-light" hx-get="{% url 'user:change_password' %}" hx-swap="none">
|
9
|
+
<span>{% translate 'Change Password' %}</span>
|
10
|
+
</button>
|
11
|
+
<button class="button is-light" hx-get="{% url 'user:change_email' %}" hx-swap="none">
|
12
|
+
<span>{% translate 'Change E-Mail' %}</span>
|
13
|
+
</button>
|
14
|
+
{% endif %}
|
15
|
+
{% endpartialdef %}
|
16
|
+
|
17
|
+
{% partialdef data %}
|
18
|
+
<section class="box">
|
19
|
+
<form id="user-form" hx-post="{% url 'user:detail' %}" hx-trigger="change changed" hx-select="#user-form" hx-swap="outerHTML" hx-select-oob="#navbar-user-name">
|
20
|
+
{% csrf_token %}
|
21
|
+
<div class="columns">
|
22
|
+
<div class="column">
|
23
|
+
{% include 'ui/form_error.html' %}
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
<div class="columns m-0">
|
27
|
+
<div class="column is-6">
|
28
|
+
{% translate 'Username' as username %}
|
29
|
+
{{ form.username|wrap_label:username }}
|
30
|
+
{{ form.first_name|wrap_label }}
|
31
|
+
{{ form.last_name|wrap_label }}
|
32
|
+
</div>
|
33
|
+
<div class="column is-6">
|
34
|
+
{% if not user.is_managed %}
|
35
|
+
{{ user|wrap_model_field:'email' }}
|
36
|
+
{% endif %}
|
37
|
+
{{ form.language_code|wrap_label }}
|
38
|
+
{{ form.theme|wrap_label }}
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
</form>
|
42
|
+
</section>
|
43
|
+
{% endpartialdef %}
|
accrete/contrib/user/views.py
CHANGED
@@ -40,21 +40,21 @@ def user_detail(request):
|
|
40
40
|
initial={'language_code': request.user.language_code},
|
41
41
|
instance=request.user
|
42
42
|
)
|
43
|
-
|
44
|
-
title=_('User Preferences'),
|
45
|
-
extra=dict(
|
46
|
-
user=request.user,
|
47
|
-
form=form
|
48
|
-
)
|
49
|
-
).dict()
|
43
|
+
refresh = False
|
50
44
|
if request.method == 'POST':
|
51
45
|
form = save_form(UserForm(request.POST, instance=request.user))
|
52
|
-
ctx.update(form=form)
|
53
46
|
if form.is_saved:
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
47
|
+
refresh = True
|
48
|
+
res = ui.WindowResponse(
|
49
|
+
title=str(_('User Preferences')),
|
50
|
+
overview_template='user/user_preferences.html#data',
|
51
|
+
header_template='user/user_preferences.html#header',
|
52
|
+
context=dict(user=request.user, form=form),
|
53
|
+
is_centered=True
|
54
|
+
).response(request, replace_body=False)
|
55
|
+
if refresh:
|
56
|
+
res.headers['HX-Refresh'] = 'true'
|
57
|
+
return res
|
58
58
|
|
59
59
|
|
60
60
|
@login_required()
|
@@ -62,15 +62,7 @@ def user_change_password(request):
|
|
62
62
|
if request.user.is_managed:
|
63
63
|
return HttpResponseForbidden()
|
64
64
|
form = ChangePasswordForm(instance=request.user)
|
65
|
-
|
66
|
-
title=_('Change Password'),
|
67
|
-
modal_id='change-password',
|
68
|
-
blocking=True,
|
69
|
-
extra=dict(
|
70
|
-
form=form,
|
71
|
-
user=request.user
|
72
|
-
)
|
73
|
-
).dict()
|
65
|
+
update = bool(request.method == 'POST')
|
74
66
|
if request.method == 'POST':
|
75
67
|
form = save_form(ChangePasswordForm(request.POST, instance=request.user))
|
76
68
|
if form.is_saved:
|
@@ -79,9 +71,13 @@ def user_change_password(request):
|
|
79
71
|
resolve_url('user:detail')
|
80
72
|
+ f'?{request.GET.urlencode()}'
|
81
73
|
)
|
82
|
-
|
83
|
-
|
84
|
-
|
74
|
+
return ui.ModalResponse(
|
75
|
+
title=str(_('Change Password')),
|
76
|
+
modal_id='change-password',
|
77
|
+
template='user/change_password.html',
|
78
|
+
is_update=update,
|
79
|
+
context=dict(form=form, user=request.user)
|
80
|
+
).response(request)
|
85
81
|
|
86
82
|
|
87
83
|
@login_required()
|
@@ -89,19 +85,22 @@ def user_change_email(request):
|
|
89
85
|
if request.user.is_managed:
|
90
86
|
return HttpResponseForbidden()
|
91
87
|
form = ChangeEmailForm(instance=request.user)
|
92
|
-
|
93
|
-
title=_('Change E-Mail'),
|
94
|
-
modal_id='change-email',
|
95
|
-
blocking=True,
|
96
|
-
extra=dict(
|
97
|
-
form=form,
|
98
|
-
user=request.user
|
99
|
-
)
|
100
|
-
).dict()
|
88
|
+
update = bool(request.method == 'POST')
|
101
89
|
if request.method == 'POST':
|
102
90
|
form = save_form(ChangeEmailForm(request.POST, instance=request.user))
|
103
91
|
if form.is_saved:
|
104
|
-
return redirect(
|
105
|
-
|
106
|
-
|
107
|
-
|
92
|
+
return redirect(
|
93
|
+
resolve_url('user:detail')
|
94
|
+
+ f'?{request.GET.urlencode()}'
|
95
|
+
)
|
96
|
+
return ui.ModalResponse(
|
97
|
+
title=str(_('Change E-Mail')),
|
98
|
+
modal_id='change-email',
|
99
|
+
template='user/change_email.html',
|
100
|
+
is_update=update,
|
101
|
+
context=dict(form=form, user=request.user)
|
102
|
+
).response(request)
|
103
|
+
|
104
|
+
|
105
|
+
def password_forgotten(request):
|
106
|
+
return render(request, 'user/')
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Generated by Django 5.2.1 on 2025-05-24 09:10
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
|
5
|
+
|
6
|
+
class Migration(migrations.Migration):
|
7
|
+
|
8
|
+
dependencies = [
|
9
|
+
('accrete', '0007_accessgroup_description'),
|
10
|
+
]
|
11
|
+
|
12
|
+
operations = [
|
13
|
+
migrations.AlterField(
|
14
|
+
model_name='member',
|
15
|
+
name='access_groups',
|
16
|
+
field=models.ManyToManyField(blank=True, through='accrete.MemberAccessGroupRel', through_fields=('member', 'access_group'), to='accrete.accessgroup'),
|
17
|
+
),
|
18
|
+
migrations.AlterField(
|
19
|
+
model_name='tenant',
|
20
|
+
name='access_groups',
|
21
|
+
field=models.ManyToManyField(blank=True, through='accrete.TenantAccessGroupRel', through_fields=('tenant', 'access_group'), to='accrete.accessgroup'),
|
22
|
+
),
|
23
|
+
]
|
accrete/utils/__init__.py
CHANGED
accrete/utils/forms.py
CHANGED
@@ -26,14 +26,22 @@ class FormResult:
|
|
26
26
|
return self.form.__getitem__(item)
|
27
27
|
|
28
28
|
|
29
|
-
def save_form(
|
29
|
+
def save_form(
|
30
|
+
form: Form | ModelForm,
|
31
|
+
*,
|
32
|
+
commit: bool = True,
|
33
|
+
check_changed: bool = False,
|
34
|
+
reraise: bool = False
|
35
|
+
) -> FormResult:
|
30
36
|
if not hasattr(form, 'save'):
|
31
37
|
raise AttributeError('Form must have method "save" implemented.')
|
32
38
|
result = FormResult(form=form)
|
39
|
+
changed = not check_changed or form.has_changed()
|
33
40
|
try:
|
34
41
|
if form.is_valid():
|
35
|
-
|
36
|
-
|
42
|
+
if changed:
|
43
|
+
with transaction.atomic():
|
44
|
+
result.res = form.save(commit=commit)
|
37
45
|
result.is_saved = True
|
38
46
|
except Exception as e:
|
39
47
|
result.save_error = repr(e)
|
accrete/utils/views.py
CHANGED
@@ -134,8 +134,7 @@ def cast_param(params: dict, param: str, cast_to: Callable, default):
|
|
134
134
|
|
135
135
|
|
136
136
|
def method_not_allowed(method: str, allowed: list[str]) -> HttpResponseNotAllowed | None:
|
137
|
-
if method
|
138
|
-
return HttpResponseNotAllowed(allowed)
|
137
|
+
return None if method in allowed else HttpResponseNotAllowed(allowed)
|
139
138
|
|
140
139
|
|
141
140
|
def render_templates(
|
accrete/views.py
CHANGED
@@ -24,16 +24,15 @@ class TenantRequiredMixin(LoginRequiredMixin):
|
|
24
24
|
MEMBER_GROUPS: list[str | tuple[str]] = []
|
25
25
|
|
26
26
|
def dispatch(self, request, *args, **kwargs):
|
27
|
-
res = super().dispatch(request, *args, **kwargs)
|
28
27
|
if not self.get_tenant():
|
29
28
|
return self.handle_tenant_not_set()
|
30
29
|
if self.request.user.is_superuser:
|
31
|
-
return
|
30
|
+
return super().dispatch(request, *args, **kwargs)
|
32
31
|
if not self.check_tenant_group():
|
33
32
|
return self.handle_tenant_group_not_set()
|
34
33
|
if not self.check_member_group():
|
35
34
|
return self.handle_member_group_not_set()
|
36
|
-
return
|
35
|
+
return super().dispatch(request, *args, **kwargs)
|
37
36
|
|
38
37
|
def handle_tenant_not_set(self):
|
39
38
|
return redirect(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: accrete
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.144
|
4
4
|
Summary: Django Shared Schema Multi Tenant
|
5
5
|
Author-email: Benedikt Jilek <benedikt.jilek@pm.me>
|
6
6
|
License: Copyright (c) 2025 Benedikt Jilek
|
@@ -31,7 +31,7 @@ Classifier: Operating System :: OS Independent
|
|
31
31
|
Classifier: Programming Language :: Python :: 3
|
32
32
|
Classifier: Topic :: Internet :: WWW/HTTP
|
33
33
|
Requires-Python: >=3.10
|
34
|
-
Requires-Dist: django>=5.
|
34
|
+
Requires-Dist: django>=5.2
|
35
35
|
Provides-Extra: contrib
|
36
36
|
Requires-Dist: celery>=5.3.4; extra == 'contrib'
|
37
37
|
Requires-Dist: django-celery-beat; extra == 'contrib'
|
@@ -12,7 +12,7 @@ accrete/storage.py,sha256=Jp3oE_uPMqgarjS_G49KDFrR2eSe4XuIJK9oAF_QBxk,1288
|
|
12
12
|
accrete/tenant.py,sha256=vfalmdfDsjYbl-ol3RqvsTC-YnuQs0JuSC7o85UInG0,2289
|
13
13
|
accrete/tests.py,sha256=Agltbzwwh5htvq_Qi9vqvxutzmg_GwgPS_N19xJZRlw,7197
|
14
14
|
accrete/urls.py,sha256=goDFR-yhOlLLy7AMi9pmh2aBkxdtZtwXNg6mwI2zPhU,227
|
15
|
-
accrete/views.py,sha256=
|
15
|
+
accrete/views.py,sha256=O8VytX3LtDizhWla_uRdXUiRnfGbgs9Z4xtubwqIOA4,5883
|
16
16
|
accrete/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
17
|
accrete/contrib/country/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
18
|
accrete/contrib/country/admin.py,sha256=0dAcFPfC8c80fhKKOL26-5Wl1uWXBYrkUJEjo2sEkk4,329
|
@@ -23,7 +23,7 @@ accrete/contrib/country/migrations/0002_auto_20250219_1759.py,sha256=hSP0WEErHHJ
|
|
23
23
|
accrete/contrib/country/migrations/0003_alter_country_options.py,sha256=0reOOdHuApMA5pw4ga6BW63TCG2U1i8T8oSug7EjUXw,428
|
24
24
|
accrete/contrib/country/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
25
|
accrete/contrib/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
26
|
-
accrete/contrib/log/admin.py,sha256=
|
26
|
+
accrete/contrib/log/admin.py,sha256=g-wdWF2O62rR0e_rLSgof_z8m42Qqv5VBrl_sFB0qlo,1212
|
27
27
|
accrete/contrib/log/apps.py,sha256=O0Cje3MmpxPToJVgO195lBg0tRCy9Ou87-ntcdGBKM0,369
|
28
28
|
accrete/contrib/log/config.py,sha256=vRzPVbiUfpo5NGtgiJv5mEKR_h3qsYI_brxjni6-Z-Y,132
|
29
29
|
accrete/contrib/log/helper.py,sha256=n5QXPf4Lo8NvxDaJifZs4QVNJdiNyr17e_z26QT9V-U,2514
|
@@ -55,21 +55,20 @@ accrete/contrib/system_mail/admin.py,sha256=9hXwwfZn446juyRoBOygLWm12X6N9waRC-1L
|
|
55
55
|
accrete/contrib/system_mail/apps.py,sha256=yIWgsa5GV8NPOJBtDZQJljSZ5v_mOP6VJrTfo_HkLF8,169
|
56
56
|
accrete/contrib/system_mail/forms.py,sha256=AQlQW0hW3KM5cU-y02DWb7HlCD4pcJAD7L5UZmqmnTc,750
|
57
57
|
accrete/contrib/system_mail/models.py,sha256=mTx8YAtyyrUE2B8iKQDyJVsUqN1EGHg8XKgdoWibZ9g,880
|
58
|
-
accrete/contrib/system_mail/tasks.py,sha256=
|
58
|
+
accrete/contrib/system_mail/tasks.py,sha256=Q9KLh_exm_KTr7ZfyNJ6KPGh5P-Nkipf0tScWRyzZUQ,1330
|
59
59
|
accrete/contrib/system_mail/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
|
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=DTl4vnTWdYTdChIPv--iYzRGAKi9uVx6NGxrF36iO6Q,365
|
64
64
|
accrete/contrib/ui/admin.py,sha256=suMo4x8I3JBxAFBVIdE-5qnqZ6JAZV0FESABHOSc-vg,63
|
65
65
|
accrete/contrib/ui/apps.py,sha256=E0ao2ox6PQ3ldfeR17FXJUUJuGiWjm2DPCxHbPXGzls,152
|
66
|
-
accrete/contrib/ui/
|
67
|
-
accrete/contrib/ui/filter.py,sha256=zLTWWSvsfvwBMNWgpZqP2kRKXCVW_50mhTQyJA36ywo,13323
|
66
|
+
accrete/contrib/ui/filter.py,sha256=WWELsSZF-v7FxAWw1gGvYHFBB0BhmQWuWacI_joTKas,13703
|
68
67
|
accrete/contrib/ui/middleware.py,sha256=QprWR8FXK9iMPIvLQAeYASaUJSW0uD9BHoYroMKrph0,1560
|
69
68
|
accrete/contrib/ui/models.py,sha256=Vjc0p2XbAPgE6HyTF6vll98A4eDhA5AvaQqsc4kQ9AQ,57
|
69
|
+
accrete/contrib/ui/response.py,sha256=vsSr4P3icnGflHv9zCfozlYUPESwtEEiugFAYUKQn9M,15482
|
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=f660YNavcQQkO6TtpnEBsT2O3KoJk-M5wgBnhnWB1EI,2563
|
73
72
|
accrete/contrib/ui/views.py,sha256=5VUbP0jgMcLMv9-3AKxkV315RA0qXuw5PmTRejPc0Yg,1136
|
74
73
|
accrete/contrib/ui/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
75
74
|
accrete/contrib/ui/static/bulma/LICENSE,sha256=--fY7Bi3Lt7RXXnKc9pe756OJY9fGv-D5OmT5pdSJ5w,1080
|
@@ -168,12 +167,11 @@ accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.scss,sha256=1tXoYLlK
|
|
168
167
|
accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.scss,sha256=NRrD7Euz_mfDI02D92a63M6H4UhArjhWy3g5DIhQr5o,366
|
169
168
|
accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.scss,sha256=gyRiEug6frpDJEaxZ7VybdApnmNS5R5A9Zn1R0yWLJg,335
|
170
169
|
accrete/contrib/ui/static/bulma/versions/bulma-prefixed.scss,sha256=cDhte1VyFupdjYFXpUyQb7wGB8aUKDGYuKluZCY5CtA,133
|
171
|
-
accrete/contrib/ui/static/css/accrete.css,sha256=
|
172
|
-
accrete/contrib/ui/static/css/accrete.css.map,sha256=
|
173
|
-
accrete/contrib/ui/static/css/accrete.scss,sha256=
|
170
|
+
accrete/contrib/ui/static/css/accrete.css,sha256=C5GVDuOcSiCVczvpvIzGAmpZQ7_VFbU-0Z_CQ_RtDGE,8208
|
171
|
+
accrete/contrib/ui/static/css/accrete.css.map,sha256=r0fiRbfcq57rvMPOC3RZvz7DGKiglLzC2fs5Y8-cHGw,4802
|
172
|
+
accrete/contrib/ui/static/css/accrete.scss,sha256=lVgtZx6HsInVdV0LVO0JVijoS6wBupi4GiPhRpQvQ4I,8261
|
174
173
|
accrete/contrib/ui/static/css/fa.css,sha256=wiz7ZSCn_btzhjKDQBms9Hx4sSeUYsDrTLg7roPstac,102641
|
175
174
|
accrete/contrib/ui/static/css/icons.css,sha256=5550KHsaayeEtRaUdf0h7esQhyec-_5ZfecZ_sOC6v0,6334
|
176
|
-
accrete/contrib/ui/static/css/.sass-cache/15adf1eed05371361b08787c918a7f18fc15be79/accrete.scssc,sha256=COJYmUzNErZkHzYxo3GVAqn7leI8NHOyD_YSii9XjHU,71246
|
177
175
|
accrete/contrib/ui/static/icons/Logo.svg,sha256=hGZuxrAa-LRpFavFiF8Lnc7X9OQcqmb6Xl_dxx-27hM,1861
|
178
176
|
accrete/contrib/ui/static/icons/accrete.svg,sha256=CWHJKIgk3hxL7xIaFSz2j1cK-eF1TroCbjcF58bgOIs,1024
|
179
177
|
accrete/contrib/ui/static/js/alpine-3.14.9.js,sha256=tgDjY9mdlURNtUrL-y3v_smueSqpmgkim82geOW1VkM,44758
|
@@ -197,28 +195,30 @@ accrete/contrib/ui/templates/django/forms/widgets/input.html,sha256=FCLULKMx0eNl
|
|
197
195
|
accrete/contrib/ui/templates/django/forms/widgets/select.html,sha256=uSfDpOQox2mEKDm9LWJ6jg5rCa3jCbHHTcmOadFLlBg,455
|
198
196
|
accrete/contrib/ui/templates/django/forms/widgets/text.html,sha256=MSmLlQc7PsPoDLVtTOOiWNprrsPriNr712yFxaHyDIo,47
|
199
197
|
accrete/contrib/ui/templates/django/forms/widgets/textarea.html,sha256=c9BTedqb3IkXLyVYd0p9pR8DFnsXCNGoxVBWZTk_Fic,278
|
200
|
-
accrete/contrib/ui/templates/ui/
|
198
|
+
accrete/contrib/ui/templates/ui/content.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
199
|
+
accrete/contrib/ui/templates/ui/content_right.html,sha256=aOFjbtXjjlqwmHpGoEpAUz6LtLGSTM6mX_RAO5-aM6k,380
|
200
|
+
accrete/contrib/ui/templates/ui/detail.html,sha256=2yVoJ5rsRKCUoId2NC7ds8l5q1z6Nl7VlLA3bSsxXMM,295
|
201
201
|
accrete/contrib/ui/templates/ui/favicon.html,sha256=ZSK6qDGV4Cexgt0VA3KOHYN100yZHOFjfOiFZVudWg0,90
|
202
202
|
accrete/contrib/ui/templates/ui/form_error.html,sha256=WWqfFWyJ_LCzm5IkxXztn23GFak5wyM2HZcmiZ3Eq9s,417
|
203
|
-
accrete/contrib/ui/templates/ui/layout.html,sha256=
|
204
|
-
accrete/contrib/ui/templates/ui/list.html,sha256=
|
205
|
-
accrete/contrib/ui/templates/ui/list_update.html,sha256=
|
206
|
-
accrete/contrib/ui/templates/ui/message.html,sha256=
|
207
|
-
accrete/contrib/ui/templates/ui/modal.html,sha256=
|
203
|
+
accrete/contrib/ui/templates/ui/layout.html,sha256=r3ZylKY2iPK8HwNcRPSzuJ4dfEQKQMGFCu7CBBE9gUg,13674
|
204
|
+
accrete/contrib/ui/templates/ui/list.html,sha256=xyEUYwQKcj-65CO5Te8ixQcUoUj_bh4nmN9cpHaO9uM,2437
|
205
|
+
accrete/contrib/ui/templates/ui/list_update.html,sha256=uHwdVQFGwDq0wEbZ6jtSnII6G7xLruivIlOX5dVGlz8,274
|
206
|
+
accrete/contrib/ui/templates/ui/message.html,sha256=dQnPNkHIrrOzelXCTO8CLWG5ufmxJ8MuWp66YLZbmro,773
|
207
|
+
accrete/contrib/ui/templates/ui/modal.html,sha256=3FzvnFVWvwRQ_r1-2qd9N5wYIOh6_oYDDp7uk6XoJPE,3481
|
208
208
|
accrete/contrib/ui/templates/ui/oob.html,sha256=lZHIBBYclefbGkKguS1A7vrtOhODJizbSRaGAAHDvG8,267
|
209
209
|
accrete/contrib/ui/templates/ui/table.html,sha256=u6JJz1FykuljZiiC2hL83hy8RbMeXcSH8xuU1ji2SHc,3939
|
210
|
-
accrete/contrib/ui/templates/ui/table_row_update.html,sha256=
|
211
|
-
accrete/contrib/ui/templates/ui/filter/filter.html,sha256=
|
210
|
+
accrete/contrib/ui/templates/ui/table_row_update.html,sha256=Jvt0wlq4btlIRk1RoSv467nT0MUBn7OwC1EbzawDej4,409
|
211
|
+
accrete/contrib/ui/templates/ui/filter/filter.html,sha256=GOTXouHH4RSCFsIzg1UPFAcmKaNNxTPmRj5Bx9K1m4o,759
|
212
212
|
accrete/contrib/ui/templates/ui/filter/query_input.html,sha256=Qg_41fODXMgL534ohktb0QOxNzAEbaeBzAajJCEK7Pg,2035
|
213
213
|
accrete/contrib/ui/templates/ui/filter/query_operator.html,sha256=h4WWLDnse6DK5Rb_0TTb0wqWxhvY_g3qjwx8_eENMuI,569
|
214
214
|
accrete/contrib/ui/templates/ui/filter/query_params.html,sha256=wCkyZ9oSK_ivraNiL-UAY_9TflYw5EspnHHm6V6uOzk,9548
|
215
|
-
accrete/contrib/ui/templates/ui/filter/query_tags.html,sha256=
|
216
|
-
accrete/contrib/ui/templates/ui/templatetags/field.html,sha256=
|
217
|
-
accrete/contrib/ui/templates/ui/widgets/model_search_select.html,sha256=
|
218
|
-
accrete/contrib/ui/templates/ui/widgets/model_search_select_multi.html,sha256=
|
215
|
+
accrete/contrib/ui/templates/ui/filter/query_tags.html,sha256=ooeIwIwvhT0fG5SMAuLoMquTVUmYf5n50DM-3gC_iAo,1567
|
216
|
+
accrete/contrib/ui/templates/ui/templatetags/field.html,sha256=njmCBUBpLQsSu1r740PMXuh5gNfjDxI6Lmo_dm4JTqw,776
|
217
|
+
accrete/contrib/ui/templates/ui/widgets/model_search_select.html,sha256=AUlWN2gKhHk_tWP1-KGel5ifaRMTF60MUtgbap7CGQ4,2938
|
218
|
+
accrete/contrib/ui/templates/ui/widgets/model_search_select_multi.html,sha256=NV_PWH8-3TqSfJT2l4aN3TOCFyYWxxtCQ9sh6X8gML0,4686
|
219
219
|
accrete/contrib/ui/templates/ui/widgets/model_search_select_options.html,sha256=4Wky0XkYWZlIKXTXzGjJkJTX3H9rhjXTY1hYai3Q3TA,242
|
220
220
|
accrete/contrib/ui/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
221
|
-
accrete/contrib/ui/templatetags/ui.py,sha256=
|
221
|
+
accrete/contrib/ui/templatetags/ui.py,sha256=cWWgzjQKgcxy6uAJZlIJzeP-O3oqFjbrCZrZdnxNUVk,4924
|
222
222
|
accrete/contrib/ui/widgets/__init__.py,sha256=W_y10jfu37lygp4frXuKFSGec97gpNbWskG6DMhTKtY,69
|
223
223
|
accrete/contrib/ui/widgets/search_select.py,sha256=zKmOt54QsxUobNkDNEA2ut3pPAl8a5DqmEpcfam1l1I,3762
|
224
224
|
accrete/contrib/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -230,7 +230,7 @@ accrete/contrib/user/middleware.py,sha256=qblcujwJsthopagyT-hPFq4HsMyGt-VvqZw5TQ
|
|
230
230
|
accrete/contrib/user/models.py,sha256=8vgDZ2Jf-aFOC12W1vKObaK9FJUwcuWwQWqAi2hXQZg,6257
|
231
231
|
accrete/contrib/user/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
|
232
232
|
accrete/contrib/user/urls.py,sha256=_fBa--3NfyYN10Td7PGHpetJYy42SMqTyCCXhgynkEQ,407
|
233
|
-
accrete/contrib/user/views.py,sha256=
|
233
|
+
accrete/contrib/user/views.py,sha256=O59SwLGpgaihCHn-1vNVsbVSrNFx1-n2YQFQYmFlC6E,3460
|
234
234
|
accrete/contrib/user/locale/de/LC_MESSAGES/django.mo,sha256=p3rgUg6WltAVIMkQsjvjBqTsd_usLhSr1GH4Cyltc2c,433
|
235
235
|
accrete/contrib/user/locale/de/LC_MESSAGES/django.po,sha256=f_Nxpo3HTm2L3f3zoHLfeWsZ-4IQp_EEVSku6TCZSvw,1870
|
236
236
|
accrete/contrib/user/migrations/0001_initial.py,sha256=JWfM9PcMDfkJUdCjLWuWieGs6643qP0KdbCyr5uAZoY,2950
|
@@ -246,7 +246,8 @@ accrete/contrib/user/templates/user/accrete_navbar_end_dropdown.html,sha256=suPo
|
|
246
246
|
accrete/contrib/user/templates/user/change_email.html,sha256=w9gBnU_O45YchY0EqD9mUK5oeDaD4cN92tHN80QjReA,815
|
247
247
|
accrete/contrib/user/templates/user/change_password.html,sha256=1U7cI-xshsy_nhSj3TUqL3tPtYaBF17XFDgJHXXDzIw,1021
|
248
248
|
accrete/contrib/user/templates/user/login.html,sha256=SXbxgq3baEch3ksGMsZqIws5heqAtpkdCLAFX3SLhtQ,2669
|
249
|
-
accrete/contrib/user/templates/user/
|
249
|
+
accrete/contrib/user/templates/user/password_forgotten.html,sha256=aoNR9VUhLkDFLIQ3NUA2Oh19bFlro0ZXvcRUdGDNPnc,30
|
250
|
+
accrete/contrib/user/templates/user/user_preferences.html,sha256=s-WmVASO0-5R2PY-y_ExS5kl9yOtMQpElVH3nKLqW0g,1646
|
250
251
|
accrete/contrib/user_registration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
251
252
|
accrete/contrib/user_registration/admin.py,sha256=kwmGTsg4Hii-lsw9-UaJG7AhQ4k4SPi48GSrtpZ4YR4,119
|
252
253
|
accrete/contrib/user_registration/apps.py,sha256=mYu3fuuubfjImeJHk4D_Wd6Edw2r3oUNXGcFbAkhir4,181
|
@@ -267,14 +268,15 @@ accrete/migrations/0004_rename_accessgroupmember_memberaccessgrouprel_and_more.p
|
|
267
268
|
accrete/migrations/0005_accessgroup_apply_on_alter_member_access_groups_and_more.py,sha256=1ZL_PG2W_5h1x1oGAUALn2Ks0kzbFusHF7XEXE1J9Pg,996
|
268
269
|
accrete/migrations/0006_alter_member_user.py,sha256=l1m1uaP1q8yaCqX2cWdzRcL-fe4VLb1SqQmP966weNQ,643
|
269
270
|
accrete/migrations/0007_accessgroup_description.py,sha256=T8BX0gSckC_fM_uD6a5-fdD-ucAn54vyY7_8o0tDIXA,429
|
271
|
+
accrete/migrations/0008_alter_member_access_groups_and_more.py,sha256=U2VpQJkLsajpL-rvzx-co5V3jYSxMnvkvjSznyVkr34,782
|
270
272
|
accrete/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
271
|
-
accrete/utils/__init__.py,sha256=
|
273
|
+
accrete/utils/__init__.py,sha256=xXpPIImuZFRFIc8Sg8j6-OWOiJZGAtX4iphdXcxAYM0,328
|
272
274
|
accrete/utils/dates.py,sha256=apM6kt6JhGrKgoT0jfav1W-8AUVTxNc9xt3fJQ2n0JI,1492
|
273
|
-
accrete/utils/forms.py,sha256=
|
275
|
+
accrete/utils/forms.py,sha256=naV4urdfvmpxcx5Vf3Fo72M5Fy8DjGg5-vkysMKptbA,3914
|
274
276
|
accrete/utils/log.py,sha256=BH0MBDweAjx30wGBO4F3sFhbgkSoEs7T1lLLjlYZNnA,407
|
275
277
|
accrete/utils/models.py,sha256=2xTacvcpmDK_Bp4rAK7JdVLf8HU009LYNJ6eSpMgYZI,1014
|
276
|
-
accrete/utils/views.py,sha256=
|
277
|
-
accrete-0.0.
|
278
|
-
accrete-0.0.
|
279
|
-
accrete-0.0.
|
280
|
-
accrete-0.0.
|
278
|
+
accrete/utils/views.py,sha256=mHfcKNDOiq-38LQ6tz9pDPQt-xs03b2qMxwJClprqu8,5022
|
279
|
+
accrete-0.0.144.dist-info/METADATA,sha256=cq1cGVRjyQjJ2j6-CAASXQVJvjUIq4VkL2ok6--mcOo,4953
|
280
|
+
accrete-0.0.144.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
281
|
+
accrete-0.0.144.dist-info/licenses/LICENSE,sha256=vHwb4Qnv8UfYKFiCWyTuRGsi49x19UQwHRCky3b2_NE,1057
|
282
|
+
accrete-0.0.144.dist-info/RECORD,,
|
accrete/contrib/ui/context.py
DELETED
@@ -1,123 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
import re
|
3
|
-
from dataclasses import dataclass, field
|
4
|
-
from django.core import paginator
|
5
|
-
from django.db.models import QuerySet, Model
|
6
|
-
from .filter import Filter
|
7
|
-
|
8
|
-
_logger = logging.getLogger(__name__)
|
9
|
-
|
10
|
-
|
11
|
-
@dataclass(kw_only=True)
|
12
|
-
class BaseContext:
|
13
|
-
|
14
|
-
extra: dict = field(default_factory=dict)
|
15
|
-
|
16
|
-
def __post_init__(self):
|
17
|
-
for key, value in self.extra.items():
|
18
|
-
setattr(self, key, value)
|
19
|
-
|
20
|
-
def dict(self):
|
21
|
-
return {
|
22
|
-
attr: getattr(self, attr, None) for attr
|
23
|
-
in filter(lambda x: not x.startswith('_'), self.__dict__)
|
24
|
-
}
|
25
|
-
|
26
|
-
|
27
|
-
@dataclass(kw_only=True)
|
28
|
-
class Context(BaseContext):
|
29
|
-
|
30
|
-
title: str = ''
|
31
|
-
|
32
|
-
|
33
|
-
@dataclass
|
34
|
-
class ListContext(Context):
|
35
|
-
|
36
|
-
page: paginator.Page
|
37
|
-
queryset: QuerySet
|
38
|
-
endless_scroll: bool = True
|
39
|
-
filter: Filter = None
|
40
|
-
column_count: int = 1
|
41
|
-
column_height: int = 150
|
42
|
-
column_height_unit: str = 'px'
|
43
|
-
|
44
|
-
def __post_init__(self):
|
45
|
-
super().__post_init__()
|
46
|
-
if self.column_count not in range(1, 13):
|
47
|
-
_logger.warning(
|
48
|
-
'ListContext parameter column_count should be in range 1 - 12'
|
49
|
-
)
|
50
|
-
|
51
|
-
|
52
|
-
@dataclass
|
53
|
-
class ListUpdateContext(BaseContext):
|
54
|
-
|
55
|
-
object: Model
|
56
|
-
template: str
|
57
|
-
|
58
|
-
|
59
|
-
@dataclass
|
60
|
-
class TableContext(Context):
|
61
|
-
|
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
|
-
filter: Filter = None
|
69
|
-
|
70
|
-
|
71
|
-
@dataclass
|
72
|
-
class TableRowContext(BaseContext):
|
73
|
-
|
74
|
-
object: Model
|
75
|
-
fields: list[str]
|
76
|
-
queryset: QuerySet
|
77
|
-
footer: dict = field(default_factory=dict)
|
78
|
-
|
79
|
-
|
80
|
-
@dataclass
|
81
|
-
class ModalContext(BaseContext):
|
82
|
-
|
83
|
-
title: str
|
84
|
-
modal_id: str
|
85
|
-
blocking: bool = False
|
86
|
-
|
87
|
-
def __post_init__(self):
|
88
|
-
super().__post_init__()
|
89
|
-
self.modal_id = re.sub(r'[^A-Za-z-]+', '', self.modal_id).strip('-')
|
90
|
-
|
91
|
-
|
92
|
-
@dataclass(kw_only=True)
|
93
|
-
class OobContext(BaseContext):
|
94
|
-
|
95
|
-
template: str
|
96
|
-
id: str = None
|
97
|
-
swap: str = 'true'
|
98
|
-
tag: str = 'div'
|
99
|
-
|
100
|
-
def dict(self) -> dict:
|
101
|
-
res = {
|
102
|
-
attr: getattr(self, attr, None) for attr
|
103
|
-
in filter(
|
104
|
-
lambda x:
|
105
|
-
not x.startswith('_')
|
106
|
-
and x not in ['template', 'id', 'swap', 'tag'],
|
107
|
-
self.__dict__
|
108
|
-
)
|
109
|
-
}
|
110
|
-
res.update({'oob': {
|
111
|
-
'template': self.template,
|
112
|
-
'id': self.id,
|
113
|
-
'swap': self.swap,
|
114
|
-
'tag': self.tag
|
115
|
-
}})
|
116
|
-
return res
|
117
|
-
|
118
|
-
|
119
|
-
@dataclass(kw_only=True)
|
120
|
-
class MessageContext(BaseContext):
|
121
|
-
|
122
|
-
persistent: bool = False
|
123
|
-
append: bool = False
|
accrete/contrib/ui/static/css/.sass-cache/15adf1eed05371361b08787c918a7f18fc15be79/accrete.scssc
DELETED
Binary file
|
accrete/contrib/ui/utils.py
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
import ast
|
2
|
-
import json
|
3
|
-
|
4
|
-
from django.http import HttpRequest, HttpResponse
|
5
|
-
from django.shortcuts import render
|
6
|
-
from django.template.loader import render_to_string
|
7
|
-
|
8
|
-
from . import OobContext
|
9
|
-
from .context import BaseContext, ModalContext
|
10
|
-
from accrete.utils import render_templates
|
11
|
-
|
12
|
-
|
13
|
-
def modal_response(
|
14
|
-
request: HttpRequest,
|
15
|
-
template: str,
|
16
|
-
context: ModalContext | dict,
|
17
|
-
update: bool = False
|
18
|
-
) -> HttpResponse:
|
19
|
-
|
20
|
-
if isinstance(context, ModalContext):
|
21
|
-
context = context.dict()
|
22
|
-
res = render(request, template, context)
|
23
|
-
if update:
|
24
|
-
res.headers['HX-Retarget'] = f'#{context["modal_id"]}'
|
25
|
-
res.headers['HX-Reswap'] = 'outerHTML'
|
26
|
-
return res
|
27
|
-
res.headers['HX-Retarget'] = 'body'
|
28
|
-
res.headers['HX-Reswap'] = 'beforeend'
|
29
|
-
return res
|
30
|
-
|
31
|
-
|
32
|
-
def detail_response(
|
33
|
-
request: HttpRequest,
|
34
|
-
header_template: str = None,
|
35
|
-
content_template: str = None,
|
36
|
-
context: BaseContext | dict = None,
|
37
|
-
extra_content: str | None = None
|
38
|
-
) -> HttpResponse:
|
39
|
-
if isinstance(context, BaseContext):
|
40
|
-
context = context.dict()
|
41
|
-
templates = [
|
42
|
-
('ui/message.html', context)
|
43
|
-
]
|
44
|
-
if header_template:
|
45
|
-
templates.append(('ui/oob.html', OobContext(
|
46
|
-
template=header_template,
|
47
|
-
swap='innerHTML:#content-right-header',
|
48
|
-
extra=context
|
49
|
-
).dict()))
|
50
|
-
if content_template:
|
51
|
-
templates.append(('ui/oob.html', OobContext(
|
52
|
-
template=content_template,
|
53
|
-
swap='innerHTML:#content-right',
|
54
|
-
extra=context
|
55
|
-
).dict()))
|
56
|
-
content = render_templates(templates, request=request)
|
57
|
-
if extra_content:
|
58
|
-
content += extra_content
|
59
|
-
res = HttpResponse(content=content)
|
60
|
-
add_trigger(res, 'activate-content-right')
|
61
|
-
return res
|
62
|
-
|
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
|
-
|
71
|
-
def add_trigger(
|
72
|
-
response: HttpResponse,
|
73
|
-
trigger: dict | str,
|
74
|
-
header: str = 'HX-Trigger'
|
75
|
-
) -> HttpResponse:
|
76
|
-
if isinstance(trigger, str):
|
77
|
-
trigger = {trigger: ''}
|
78
|
-
res_trigger = response.headers.get(header)
|
79
|
-
if not res_trigger:
|
80
|
-
response.headers[header] = json.dumps(trigger)
|
81
|
-
return response
|
82
|
-
try:
|
83
|
-
res_trigger = ast.literal_eval(response.headers.get(header, '{}'))
|
84
|
-
except SyntaxError:
|
85
|
-
res_trigger = {response.headers[header]: ''}
|
86
|
-
res_trigger.update(trigger)
|
87
|
-
response.headers[header] = json.dumps(res_trigger)
|
88
|
-
return response
|