accrete 0.0.35__py3-none-any.whl → 0.0.37__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/annotation.py +46 -0
- accrete/contrib/ui/__init__.py +12 -3
- accrete/contrib/ui/context.py +184 -257
- accrete/contrib/ui/elements.py +78 -2
- accrete/contrib/ui/filter.py +110 -44
- accrete/contrib/ui/static/css/accrete.css +128 -128
- accrete/contrib/ui/static/css/accrete.css.map +1 -1
- accrete/contrib/ui/static/css/accrete.scss +9 -9
- accrete/contrib/ui/static/js/filter.js +24 -0
- accrete/contrib/ui/static/js/htmx.min.js +1 -0
- accrete/contrib/ui/templates/ui/layout.html +134 -129
- accrete/contrib/ui/templates/ui/list.html +3 -3
- accrete/contrib/ui/templates/ui/partials/filter.html +29 -5
- accrete/contrib/ui/templates/ui/partials/header.html +7 -7
- accrete/contrib/ui/templates/ui/partials/pagination_detail.html +3 -3
- accrete/contrib/ui/templates/ui/partials/pagination_list.html +4 -4
- accrete/contrib/ui/templates/ui/table.html +18 -13
- accrete/contrib/ui/templatetags/accrete_ui.py +12 -1
- accrete/contrib/user/forms.py +0 -4
- accrete/contrib/user/templates/user/login.html +6 -12
- accrete/contrib/user/views.py +31 -21
- accrete/middleware.py +15 -0
- accrete/models.py +9 -7
- accrete/querystring.py +11 -8
- accrete/utils/models.py +14 -0
- {accrete-0.0.35.dist-info → accrete-0.0.37.dist-info}/METADATA +1 -1
- {accrete-0.0.35.dist-info → accrete-0.0.37.dist-info}/RECORD +29 -28
- accrete/contrib/ui/components.py +0 -96
- accrete/contrib/ui/querystring.py +0 -19
- {accrete-0.0.35.dist-info → accrete-0.0.37.dist-info}/WHEEL +0 -0
- {accrete-0.0.35.dist-info → accrete-0.0.37.dist-info}/licenses/LICENSE +0 -0
accrete/contrib/user/views.py
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
-
from django.
|
1
|
+
from django.utils import timezone
|
2
2
|
from django.contrib.auth.forms import AuthenticationForm
|
3
|
-
from django.contrib.auth import
|
3
|
+
from django.contrib.auth import views, update_session_auth_hash
|
4
4
|
from django.contrib.auth.decorators import login_required
|
5
|
+
from django.contrib.sessions.models import Session
|
5
6
|
from django.contrib import messages
|
7
|
+
from django.db.models import Q
|
6
8
|
from django.shortcuts import redirect, render, reverse, resolve_url
|
7
9
|
from django.utils.translation import gettext_lazy as _
|
8
10
|
from django.conf import settings
|
9
11
|
|
10
12
|
from accrete.forms import save_form
|
11
|
-
from accrete.contrib
|
13
|
+
from accrete.contrib import ui
|
12
14
|
from .forms import UserForm, ChangePasswordForm, ChangeEmailForm
|
13
15
|
|
14
16
|
|
@@ -37,15 +39,17 @@ class LogoutView(views.LogoutView):
|
|
37
39
|
|
38
40
|
@login_required()
|
39
41
|
def user_detail(request):
|
40
|
-
ctx = DetailContext(
|
41
|
-
|
42
|
+
ctx = ui.DetailContext(
|
43
|
+
title=_('Preferences'),
|
44
|
+
object=request.user,
|
45
|
+
breadcrumbs=[],
|
42
46
|
actions=[
|
43
|
-
ClientAction(_('Edit'), url=reverse('user:edit')),
|
44
|
-
ClientAction(_('Change E-Mail'), url=reverse('user:edit_email')),
|
45
|
-
ClientAction(_('Change Password'), url=reverse('user:edit_password'))
|
47
|
+
ui.ClientAction(_('Edit'), url=reverse('user:edit')),
|
48
|
+
ui.ClientAction(_('Change E-Mail'), url=reverse('user:edit_email')),
|
49
|
+
ui.ClientAction(_('Change Password'), url=reverse('user:edit_password'))
|
46
50
|
]
|
47
51
|
)
|
48
|
-
return render(request, 'user/user_detail.html', ctx
|
52
|
+
return render(request, 'user/user_detail.html', ctx)
|
49
53
|
|
50
54
|
|
51
55
|
@login_required()
|
@@ -58,7 +62,12 @@ def user_edit(request):
|
|
58
62
|
form = save_form(UserForm(request.POST, instance=request.user))
|
59
63
|
if form.is_saved:
|
60
64
|
return redirect('user:detail')
|
61
|
-
ctx = FormContext(
|
65
|
+
ctx = ui.FormContext(
|
66
|
+
title=_('Preferences'),
|
67
|
+
form=form,
|
68
|
+
form_id='form',
|
69
|
+
actions=ui.form_actions(reverse('user:detail'))
|
70
|
+
)
|
62
71
|
return render(request, 'user/user_form.html', ctx)
|
63
72
|
|
64
73
|
|
@@ -75,12 +84,12 @@ def user_change_password(request):
|
|
75
84
|
fail_silently=True
|
76
85
|
)
|
77
86
|
return redirect('user:detail')
|
78
|
-
ctx = FormContext(
|
79
|
-
request.user,
|
80
|
-
form,
|
81
|
-
request.GET.dict(),
|
87
|
+
ctx = ui.FormContext(
|
82
88
|
title=_('Change Password'),
|
83
|
-
|
89
|
+
form=form,
|
90
|
+
form_id='form',
|
91
|
+
actions=ui.form_actions(reverse('user:detail'))
|
92
|
+
)
|
84
93
|
return render(request, 'user/change_password.html', ctx)
|
85
94
|
|
86
95
|
|
@@ -96,10 +105,11 @@ def user_change_email(request):
|
|
96
105
|
fail_silently=True
|
97
106
|
)
|
98
107
|
return redirect('user:detail')
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
108
|
+
|
109
|
+
ctx = ui.FormContext(
|
110
|
+
title=_('Change Email'),
|
111
|
+
form=form,
|
112
|
+
form_id='form',
|
113
|
+
actions=ui.form_actions(reverse('user:detail'))
|
114
|
+
)
|
105
115
|
return render(request, 'user/change_email.html', ctx)
|
accrete/middleware.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
from django.utils.deprecation import MiddlewareMixin
|
2
2
|
from django.conf import settings
|
3
|
+
from django.http.response import HttpResponseRedirect, HttpResponsePermanentRedirect
|
3
4
|
from accrete.tenant import set_tenant, set_member
|
4
5
|
|
5
6
|
from .models import Tenant
|
@@ -73,3 +74,17 @@ class TenantMiddleware(MiddlewareMixin):
|
|
73
74
|
max_age=31536000
|
74
75
|
)
|
75
76
|
return response
|
77
|
+
|
78
|
+
|
79
|
+
class HtmxRedirectMiddleware(MiddlewareMixin):
|
80
|
+
|
81
|
+
@staticmethod
|
82
|
+
def process_response(request, response):
|
83
|
+
is_htmx = request.headers.get('HX-Request', 'false') == 'true'
|
84
|
+
is_redirect = isinstance(
|
85
|
+
response, (HttpResponseRedirect, HttpResponsePermanentRedirect)
|
86
|
+
)
|
87
|
+
if is_htmx and is_redirect:
|
88
|
+
response['HX-Redirect'] = response['Location']
|
89
|
+
response.status_code = 200
|
90
|
+
return response
|
accrete/models.py
CHANGED
@@ -3,16 +3,17 @@ from django.conf import settings
|
|
3
3
|
from django.utils.translation import gettext_lazy as _
|
4
4
|
from django.contrib.auth.validators import UnicodeUsernameValidator
|
5
5
|
from accrete.tenant import get_tenant
|
6
|
+
from accrete.annotation import AnnotationModelMixin, AnnotationManagerMixin
|
6
7
|
|
7
8
|
|
8
|
-
class TenantManager(models.Manager):
|
9
|
+
class TenantManager(models.Manager, AnnotationManagerMixin):
|
9
10
|
|
10
11
|
def get_queryset(self):
|
11
12
|
queryset = super().get_queryset()
|
12
13
|
tenant = get_tenant()
|
13
14
|
if tenant:
|
14
15
|
queryset = queryset.filter(tenant=tenant)
|
15
|
-
return queryset
|
16
|
+
return self.add_annotations(queryset)
|
16
17
|
|
17
18
|
def bulk_create(
|
18
19
|
self,
|
@@ -25,10 +26,11 @@ class TenantManager(models.Manager):
|
|
25
26
|
):
|
26
27
|
tenant = get_tenant()
|
27
28
|
if tenant is None and not all(obj.tenant_id for obj in objs):
|
28
|
-
raise ValueError(
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
raise ValueError(
|
30
|
+
'Tenant must be set for all objects when calling bulk_create'
|
31
|
+
)
|
32
|
+
for obj in objs:
|
33
|
+
obj.tenant_id = tenant.pk
|
32
34
|
return super().bulk_create(
|
33
35
|
objs, batch_size=batch_size, ignore_conflicts=ignore_conflicts,
|
34
36
|
update_conflicts=update_conflicts, update_fields=update_fields,
|
@@ -36,7 +38,7 @@ class TenantManager(models.Manager):
|
|
36
38
|
)
|
37
39
|
|
38
40
|
|
39
|
-
class TenantModel(models.Model):
|
41
|
+
class TenantModel(models.Model, AnnotationModelMixin):
|
40
42
|
|
41
43
|
class Meta:
|
42
44
|
abstract = True
|
accrete/querystring.py
CHANGED
@@ -6,8 +6,14 @@ from django.db.models import Model, Q, QuerySet
|
|
6
6
|
_logger = logging.getLogger(__name__)
|
7
7
|
|
8
8
|
|
9
|
-
def
|
10
|
-
|
9
|
+
def filter_from_querystring(
|
10
|
+
model: type[Model], query_string: str, order: list[str] = None
|
11
|
+
) -> QuerySet:
|
12
|
+
|
13
|
+
order = order or model._meta.ordering
|
14
|
+
return model.objects.filter(
|
15
|
+
parse_querystring(model, query_string)
|
16
|
+
).order_by(*order).distinct()
|
11
17
|
|
12
18
|
|
13
19
|
def parse_querystring(model: type[Model], query_string: str) -> Q:
|
@@ -23,7 +29,7 @@ def parse_querystring(model: type[Model], query_string: str) -> Q:
|
|
23
29
|
invert = True
|
24
30
|
term = term[1:]
|
25
31
|
|
26
|
-
parts = term.split('
|
32
|
+
parts = term.split('__')
|
27
33
|
if len(parts) == 1:
|
28
34
|
expression = Q(**{term: value})
|
29
35
|
return ~expression if invert else expression
|
@@ -31,10 +37,7 @@ def parse_querystring(model: type[Model], query_string: str) -> Q:
|
|
31
37
|
rel_path = parts[0].rstrip('__')
|
32
38
|
term = parts[1]
|
33
39
|
rel_model = get_related_model(rel_path) if rel_path else model
|
34
|
-
objects = rel_model.objects.
|
35
|
-
annotation['name']: annotation['func']
|
36
|
-
for annotation in rel_model.annotations
|
37
|
-
}).filter(Q(**{term: value}))
|
40
|
+
objects = rel_model.objects.filter(Q(**{term: value}))
|
38
41
|
expression = Q(**{
|
39
42
|
f'{rel_path}{"__" if rel_path else ""}id__in': objects.values_list('id', flat=True)
|
40
43
|
})
|
@@ -80,7 +83,7 @@ def parse_querystring(model: type[Model], query_string: str) -> Q:
|
|
80
83
|
)
|
81
84
|
return parsed_query
|
82
85
|
|
83
|
-
query_data = json.loads(query_string)
|
86
|
+
query_data = json.loads(query_string.strip('?&='))
|
84
87
|
if isinstance(query_data, dict):
|
85
88
|
query_data = [query_data]
|
86
89
|
|
accrete/utils/models.py
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
from django.db.models import Model
|
2
|
+
|
3
|
+
|
4
|
+
def get_related_model(model: type[Model], rel_path: str):
|
5
|
+
related_model = model
|
6
|
+
for part in rel_path.split('__'):
|
7
|
+
try:
|
8
|
+
related_model = related_model._meta.fields_map[part].related_model
|
9
|
+
except (AttributeError, KeyError):
|
10
|
+
try:
|
11
|
+
related_model = getattr(related_model, part).field.related_model
|
12
|
+
except AttributeError:
|
13
|
+
break
|
14
|
+
return related_model
|
@@ -1,12 +1,13 @@
|
|
1
1
|
accrete/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
accrete/admin.py,sha256=MUYUmCFlGYPowiXTbwl4_Q6Cq0-neiL53WW4P76JCLs,1174
|
3
|
+
accrete/annotation.py,sha256=-nYqDQPOixkD9qdzVZDCIA4lETH2fAZcCSxNmaY2s80,1251
|
3
4
|
accrete/apps.py,sha256=F7ynMLHJr_6bRujWtZVUzCliY2CGKiDvyUmL4F68L2E,146
|
4
5
|
accrete/config.py,sha256=eJUbvyBO3DvAD6xkVKjTAzlXy7V7EK9bVyb91girfUs,299
|
5
6
|
accrete/forms.py,sha256=nPDgSZao-vuVFRam2Py18yiet3Bar-A-qkWjwbeUDlg,11235
|
6
|
-
accrete/middleware.py,sha256=
|
7
|
-
accrete/models.py,sha256=
|
7
|
+
accrete/middleware.py,sha256=RWeHHcYCfpVO4EnG5HMS52F1y5OKRzNCuidMeq6b0zY,3176
|
8
|
+
accrete/models.py,sha256=ruPKqNeKYzqSpYRhpQ12S82iJDYxy0EjSEtNSKWeRz4,6126
|
8
9
|
accrete/queries.py,sha256=bchiqLzE1DmR9kvQ6Yyog6cNlYK_lxpztQMOx6Hy_0c,410
|
9
|
-
accrete/querystring.py,sha256=
|
10
|
+
accrete/querystring.py,sha256=TEJ-PhNj1xfA5a2gL6QwD3r33CIcUpLjr5ju0RIgd_I,3140
|
10
11
|
accrete/tenant.py,sha256=g3ZuTrQr2zqmIopNBRQeCmHEK2R3dlUme_hOV765J6U,1778
|
11
12
|
accrete/tests.py,sha256=Agltbzwwh5htvq_Qi9vqvxutzmg_GwgPS_N19xJZRlw,7197
|
12
13
|
accrete/views.py,sha256=9-sgCFe_CyG-wllAcIOLujyueiq66C-zg0U7Uf5Y2wU,2954
|
@@ -32,14 +33,12 @@ accrete/contrib/system_mail/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2
|
|
32
33
|
accrete/contrib/system_mail/views.py,sha256=xc1IQHrsij7j33TUbo-_oewy3vs03pw_etpBWaMYJl0,63
|
33
34
|
accrete/contrib/system_mail/migrations/0001_initial.py,sha256=6cwkkRXGjXvwXoMjjgmWmcPyXSTlUbhW1vMiHObk9MQ,1074
|
34
35
|
accrete/contrib/system_mail/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
|
-
accrete/contrib/ui/__init__.py,sha256=
|
36
|
+
accrete/contrib/ui/__init__.py,sha256=D_QP3FW_4IzP2c_4WTWyuRIENDA1AFrSOXWL_FNeSMY,445
|
36
37
|
accrete/contrib/ui/admin.py,sha256=suMo4x8I3JBxAFBVIdE-5qnqZ6JAZV0FESABHOSc-vg,63
|
37
38
|
accrete/contrib/ui/apps.py,sha256=E0ao2ox6PQ3ldfeR17FXJUUJuGiWjm2DPCxHbPXGzls,152
|
38
|
-
accrete/contrib/ui/
|
39
|
-
accrete/contrib/ui/
|
40
|
-
accrete/contrib/ui/
|
41
|
-
accrete/contrib/ui/filter.py,sha256=6EjHzTiqCwOjeiHNNmuvgj65VV-QCmZgCVKXAHxH5Bg,10650
|
42
|
-
accrete/contrib/ui/querystring.py,sha256=vMP_4Hn6L3jCLf6_HIscZkPgkZGe9g9Y7GfI2zZYn2A,709
|
39
|
+
accrete/contrib/ui/context.py,sha256=lBX3Ga-54cRDnbmFT28afCypbtwg65qNtjKbiQz2jmI,6242
|
40
|
+
accrete/contrib/ui/elements.py,sha256=g6wksl7hHGJb3CKmkio5rWgcpr1Eyr2vxbKVD-59lkc,1570
|
41
|
+
accrete/contrib/ui/filter.py,sha256=39Kms9jS-ruuursyUbnazrM3DrBsMSEr81Lh6EelUqs,13047
|
43
42
|
accrete/contrib/ui/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
|
44
43
|
accrete/contrib/ui/urls.py,sha256=TUBlz_CGs9InTZoxM78GSnucA73I8knoh_obt12RUHM,186
|
45
44
|
accrete/contrib/ui/views.py,sha256=WpBKMsxFFG8eG4IN7TW_TPE6i3OFF7gnLDTK7JMKti8,191
|
@@ -118,14 +117,15 @@ accrete/contrib/ui/static/bulma/sass/utilities/extends.sass,sha256=jb5Ipy_k6hBSF
|
|
118
117
|
accrete/contrib/ui/static/bulma/sass/utilities/functions.sass,sha256=tRNFJ9yQTS-GZ6ouJ7EIWiFITL7irYR7srzKwzacvUA,4896
|
119
118
|
accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.sass,sha256=JXNQHoF4YlBTUW6WSJ14_38SA9lbk6VkouzYURmlV8g,2691
|
120
119
|
accrete/contrib/ui/static/bulma/sass/utilities/mixins.sass,sha256=oijSh2f1DPqod0W5op9iVEAFbC1huMqBIJmnHRx3exc,6291
|
121
|
-
accrete/contrib/ui/static/css/accrete.css,sha256=
|
120
|
+
accrete/contrib/ui/static/css/accrete.css,sha256=XflTQHcjaGSFHjtojR1t8MWSt2MRDEQPeWH5QuU1hIo,253378
|
122
121
|
accrete/contrib/ui/static/css/accrete.css.bak,sha256=2RErGa8_tm8lFSamfW3UfqPgEVkPDejk2fh8IidW-B0,2359
|
123
|
-
accrete/contrib/ui/static/css/accrete.css.map,sha256=
|
124
|
-
accrete/contrib/ui/static/css/accrete.scss,sha256=
|
122
|
+
accrete/contrib/ui/static/css/accrete.css.map,sha256=eAGk5OIGglWaUl-B8ORQI24KwqZfYj_tkkTfEFr9MwU,55936
|
123
|
+
accrete/contrib/ui/static/css/accrete.scss,sha256=KCY4QZNNVtIvogyNYkSwxeFzCCHs1MD4-l-f5bL6QFM,5694
|
125
124
|
accrete/contrib/ui/static/css/icons.css,sha256=IMdNurvI1cUwpGG8n3UXRkxl8MqP2Eqkvyh2maeyghw,6301
|
126
125
|
accrete/contrib/ui/static/icons/Logo.svg,sha256=hGZuxrAa-LRpFavFiF8Lnc7X9OQcqmb6Xl_dxx-27hM,1861
|
127
126
|
accrete/contrib/ui/static/icons/accrete.svg,sha256=CWHJKIgk3hxL7xIaFSz2j1cK-eF1TroCbjcF58bgOIs,1024
|
128
|
-
accrete/contrib/ui/static/js/filter.js,sha256=
|
127
|
+
accrete/contrib/ui/static/js/filter.js,sha256=wMK4rIx4J8ps3uB6J1z2wRAZ5MzkAN6D8EhFQiXybjM,22864
|
128
|
+
accrete/contrib/ui/static/js/htmx.min.js,sha256=s73PXHQYl6U2SLEgf_8EaaDWGQFCm6H26I-Y69hOZp4,47755
|
129
129
|
accrete/contrib/ui/static/js/list.js,sha256=OX_81ifRmawE-1QBU5Qpq_E6sHiiNwIPleETAn9EOJw,4280
|
130
130
|
accrete/contrib/ui/templates/django/forms/widgets/attrs.html,sha256=zNxjU4Ta_eWZkh1WhrF_VIwNZ0lZyl980gSSijUK51k,195
|
131
131
|
accrete/contrib/ui/templates/django/forms/widgets/email.html,sha256=fXpbxMzAdbv_avfWC5464gD2jFng931Eq7vzbzy1-yA,48
|
@@ -136,31 +136,31 @@ accrete/contrib/ui/templates/django/forms/widgets/text.html,sha256=MSmLlQc7PsPoD
|
|
136
136
|
accrete/contrib/ui/templates/django/forms/widgets/textarea.html,sha256=c9BTedqb3IkXLyVYd0p9pR8DFnsXCNGoxVBWZTk_Fic,278
|
137
137
|
accrete/contrib/ui/templates/ui/detail.html,sha256=0sqsW_XbtLVIquXA8157ZWamnwRc4Wp-6_aZgZ5HN64,1051
|
138
138
|
accrete/contrib/ui/templates/ui/form.html,sha256=kIIG4zzNbxb5fJAVr3lI05oa3yoxyAwstMeQWLa2Z0Y,409
|
139
|
-
accrete/contrib/ui/templates/ui/layout.html,sha256=
|
140
|
-
accrete/contrib/ui/templates/ui/list.html,sha256=
|
141
|
-
accrete/contrib/ui/templates/ui/table.html,sha256=
|
142
|
-
accrete/contrib/ui/templates/ui/partials/filter.html,sha256=
|
139
|
+
accrete/contrib/ui/templates/ui/layout.html,sha256=qxLTBR16uh3ed1qm_eC-GrFkN6RYZZx0k1bX07Dcfz4,9247
|
140
|
+
accrete/contrib/ui/templates/ui/list.html,sha256=dcPS1aSN9GlsljJsTNhKMqgPe8goF1uwknZ4DIbElLU,1212
|
141
|
+
accrete/contrib/ui/templates/ui/table.html,sha256=xVSFKrjO_2YkSEO3nspHqMj8mQU4ZV8GSAQFSsAk5SI,3868
|
142
|
+
accrete/contrib/ui/templates/ui/partials/filter.html,sha256=Y2-9fwV_sjrsu-Jvuh8hseku0mQTjsnePSHemps3Tqg,3936
|
143
143
|
accrete/contrib/ui/templates/ui/partials/form_errors.html,sha256=1_TQvTdiejsn-43YSyp2YfnP52P-MFYb-HGY0DLm4oA,991
|
144
144
|
accrete/contrib/ui/templates/ui/partials/form_modal.html,sha256=FFDfI5qjOCUBSGqDjBXa8tcqN2q94wOOCNFDaiyplHQ,1032
|
145
|
-
accrete/contrib/ui/templates/ui/partials/header.html,sha256=
|
145
|
+
accrete/contrib/ui/templates/ui/partials/header.html,sha256=Fr65wv84RgcjpRr1jRdGzChaX08SVhmFhcdEmkTBmyI,2859
|
146
146
|
accrete/contrib/ui/templates/ui/partials/onchange_form.html,sha256=K5twTGqRUW1iM2dGtdWntjsJvJVo5EIzKxX2HK-H1yw,160
|
147
|
-
accrete/contrib/ui/templates/ui/partials/pagination_detail.html,sha256=
|
148
|
-
accrete/contrib/ui/templates/ui/partials/pagination_list.html,sha256=
|
147
|
+
accrete/contrib/ui/templates/ui/partials/pagination_detail.html,sha256=58nA3X7Il0FAD4VcYyr7tTGWRiVf_FN1TkImmKEpKHU,1014
|
148
|
+
accrete/contrib/ui/templates/ui/partials/pagination_list.html,sha256=9h-I5PfjViomZjoeBUZIwmx7tgWodCs4bDtjOdsPQ8c,1379
|
149
149
|
accrete/contrib/ui/templates/ui/partials/table_field.html,sha256=4oQw0na9UgHP8lo8KttyWBuDhCEeaZ8Vt9jJYJdZ5Gs,641
|
150
150
|
accrete/contrib/ui/templates/ui/partials/table_field_float.html,sha256=GH_jFdpk8wEJXv4QfO6c3URYrZGGLeuSyWwWl2cWxwQ,45
|
151
151
|
accrete/contrib/ui/templates/ui/partials/table_field_monetary.html,sha256=Wtod9vel2dD4vG8lUVLbtls4aU_2EG3p0E1QRRUSH10,166
|
152
152
|
accrete/contrib/ui/templates/ui/partials/table_field_string.html,sha256=GH_jFdpk8wEJXv4QfO6c3URYrZGGLeuSyWwWl2cWxwQ,45
|
153
153
|
accrete/contrib/ui/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
154
|
-
accrete/contrib/ui/templatetags/accrete_ui.py,sha256=
|
154
|
+
accrete/contrib/ui/templatetags/accrete_ui.py,sha256=ttu2dN5xVMOaON1gyd6Dk22TGt3RQQr97YECrwVgDmw,1593
|
155
155
|
accrete/contrib/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
156
156
|
accrete/contrib/user/admin.py,sha256=YS4iApli7XUaIl9GsEJxys2j8sepX0by88omYHjff-E,85
|
157
157
|
accrete/contrib/user/apps.py,sha256=oHDrAiHf-G57mZLyxqGJzRY2DbPprGFD-QgyVJG_ruI,156
|
158
|
-
accrete/contrib/user/forms.py,sha256=
|
158
|
+
accrete/contrib/user/forms.py,sha256=LVnRx9lcDZbSFn46zRndo1FR9qPvis5ivlXgTMp_IcM,3119
|
159
159
|
accrete/contrib/user/middleware.py,sha256=qblcujwJsthopagyT-hPFq4HsMyGt-VvqZw5TQopBjk,403
|
160
160
|
accrete/contrib/user/models.py,sha256=SFEXG9G-XY7Nuss7DT51abDv8BWLHKYJocOhQDI_1Lw,3926
|
161
161
|
accrete/contrib/user/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
|
162
162
|
accrete/contrib/user/urls.py,sha256=ktQJ3vZxDlKNUfzOxReeDLOduSdoW5z5Sz0LVFpxZGU,460
|
163
|
-
accrete/contrib/user/views.py,sha256=
|
163
|
+
accrete/contrib/user/views.py,sha256=82-RPqabxE6o7cglnfZmCUxNNRii4pmVFGiTThE4Zp0,3727
|
164
164
|
accrete/contrib/user/locale/de/LC_MESSAGES/django.mo,sha256=p3rgUg6WltAVIMkQsjvjBqTsd_usLhSr1GH4Cyltc2c,433
|
165
165
|
accrete/contrib/user/locale/de/LC_MESSAGES/django.po,sha256=f_Nxpo3HTm2L3f3zoHLfeWsZ-4IQp_EEVSku6TCZSvw,1870
|
166
166
|
accrete/contrib/user/migrations/0001_initial.py,sha256=JWfM9PcMDfkJUdCjLWuWieGs6643qP0KdbCyr5uAZoY,2950
|
@@ -168,7 +168,7 @@ accrete/contrib/user/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
|
|
168
168
|
accrete/contrib/user/templates/user/accrete_navbar_end_dropdown.html,sha256=vDFjrOZ95doOpdGYSCRlP8H-FfKUWpkYgYP8mOKcboY,481
|
169
169
|
accrete/contrib/user/templates/user/change_email.html,sha256=i9ZgDH31awO9W87E6c3_MKgQNf1ff7EYQX1nEdPqRC8,995
|
170
170
|
accrete/contrib/user/templates/user/change_password.html,sha256=wcwm5_tfPgs9V7VWdDQqhhyMpcIkiGsx2OIptF5fWMk,1498
|
171
|
-
accrete/contrib/user/templates/user/login.html,sha256=
|
171
|
+
accrete/contrib/user/templates/user/login.html,sha256=TuEH4uKK1CFV5X7nP3xPSzu2VJaoEn6APsHh-k6GiCc,1388
|
172
172
|
accrete/contrib/user/templates/user/user_detail.html,sha256=SMkghUKVncVq3KFGBxADJf_wDnLYwmK4oDTKLO0Ejlo,1445
|
173
173
|
accrete/contrib/user/templates/user/user_form.html,sha256=4o24KV940D_KsBP4YwBguwTFW9nYz1uz-RILs91M7Po,1935
|
174
174
|
accrete/contrib/user_registration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -189,7 +189,8 @@ accrete/migrations/0002_initial.py,sha256=dFOM7kdHlx7pVAh8cTDlZMtciN4O9Z547HAzEK
|
|
189
189
|
accrete/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
190
190
|
accrete/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
191
191
|
accrete/utils/dates.py,sha256=apM6kt6JhGrKgoT0jfav1W-8AUVTxNc9xt3fJQ2n0JI,1492
|
192
|
-
accrete
|
193
|
-
accrete-0.0.
|
194
|
-
accrete-0.0.
|
195
|
-
accrete-0.0.
|
192
|
+
accrete/utils/models.py,sha256=qAdWovkztpvFZHY7VzK4hGIMUjBcA9iQtqYFgz7z2ro,474
|
193
|
+
accrete-0.0.37.dist-info/METADATA,sha256=DKhGve3m6OHxG8gFRrsGmdShLC6Ttph3HlvB6_5ACQU,4892
|
194
|
+
accrete-0.0.37.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
|
195
|
+
accrete-0.0.37.dist-info/licenses/LICENSE,sha256=_7laeMIHnsd3Y2vJEXDYXq_PEXxIcjgJsGt8UIKTRWc,1057
|
196
|
+
accrete-0.0.37.dist-info/RECORD,,
|
accrete/contrib/ui/components.py
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
from dataclasses import dataclass, field
|
2
|
-
from enum import Enum
|
3
|
-
from django.db.models import Model, QuerySet, Q
|
4
|
-
|
5
|
-
DEFAULT_PAGINATE_BY = 40
|
6
|
-
|
7
|
-
|
8
|
-
class ActionMethod(Enum):
|
9
|
-
|
10
|
-
HREF = 'href'
|
11
|
-
GET = 'hx-get'
|
12
|
-
POST = 'hx-post'
|
13
|
-
PUT = 'hx-put'
|
14
|
-
DELETE = 'hx-delete'
|
15
|
-
|
16
|
-
|
17
|
-
class TableFieldAlignment(Enum):
|
18
|
-
|
19
|
-
LEFT = 'left'
|
20
|
-
CENTER = 'center'
|
21
|
-
RIGHT = 'right'
|
22
|
-
|
23
|
-
|
24
|
-
class TableFieldType(Enum):
|
25
|
-
|
26
|
-
NONE = ''
|
27
|
-
STRING = '_string'
|
28
|
-
MONETARY = '_monetary'
|
29
|
-
FLOAT = '_float'
|
30
|
-
|
31
|
-
|
32
|
-
@dataclass
|
33
|
-
class TableField:
|
34
|
-
|
35
|
-
label: str
|
36
|
-
name: str
|
37
|
-
alignment: TableFieldAlignment | Enum = TableFieldAlignment.LEFT
|
38
|
-
header_alignment: TableFieldAlignment | Enum = None
|
39
|
-
header_info: str = None
|
40
|
-
field_type: TableFieldType | Enum = TableFieldType.NONE
|
41
|
-
prefix: str = ''
|
42
|
-
suffix: str = ''
|
43
|
-
truncate_after: int = 0
|
44
|
-
template: str = None
|
45
|
-
|
46
|
-
|
47
|
-
@dataclass
|
48
|
-
class BreadCrumb:
|
49
|
-
|
50
|
-
name: str
|
51
|
-
url: str
|
52
|
-
add_url_params: bool = True
|
53
|
-
|
54
|
-
|
55
|
-
class Icon(Enum):
|
56
|
-
|
57
|
-
ADD = 'icon-add'
|
58
|
-
EDIT = 'icon-edit'
|
59
|
-
LIST = 'icon-list'
|
60
|
-
OPEN_RELATED = 'icon-open-related'
|
61
|
-
ENVELOPE = 'icon-envelope'
|
62
|
-
CLEAR = 'icon-clear'
|
63
|
-
BACKSPACE = 'icon-backspace'
|
64
|
-
FILTER = 'icon-filter'
|
65
|
-
DELETE_FILTER = 'icon-delete-filter'
|
66
|
-
SELECT = 'icon-select'
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
@dataclass
|
71
|
-
class ClientAction:
|
72
|
-
|
73
|
-
name: str
|
74
|
-
url: str = ''
|
75
|
-
method: ActionMethod = ActionMethod.HREF
|
76
|
-
query_params: str = ''
|
77
|
-
attrs: list[tuple[str, str]] = field(default_factory=list)
|
78
|
-
submit: bool = False
|
79
|
-
form_id: str = 'form'
|
80
|
-
class_list: list[str] = field(default_factory=list)
|
81
|
-
add_url_params: bool = False
|
82
|
-
icon: Icon | type[Enum] = None
|
83
|
-
|
84
|
-
def attrs_str(self):
|
85
|
-
return ' '.join([f'{str(attr[0])}={str(attr[1])}' for attr in self.attrs])
|
86
|
-
|
87
|
-
|
88
|
-
@dataclass
|
89
|
-
class List:
|
90
|
-
|
91
|
-
queryset: QuerySet
|
92
|
-
title: str = None
|
93
|
-
paginate_by: int = DEFAULT_PAGINATE_BY
|
94
|
-
breadcrumbs: list[BreadCrumb] = field(default_factory=list)
|
95
|
-
actions: list[ClientAction] = field(default_factory=list)
|
96
|
-
fields: list[TableField] = field(default_factory=list)
|
@@ -1,19 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
|
3
|
-
|
4
|
-
def load_querystring(get_params: dict) -> list:
|
5
|
-
return json.loads(get_params.get('q', '[]'))
|
6
|
-
|
7
|
-
|
8
|
-
def build_querystring(get_params: dict, extra_params: list[str] = None) -> str:
|
9
|
-
querystring = f'?q={get_params.get("q", "[]")}'
|
10
|
-
if paginate_by := get_params.get('paginate_by', False):
|
11
|
-
querystring += f'&paginate_by={paginate_by}'
|
12
|
-
if order_by := get_params.get('order_by', False):
|
13
|
-
querystring += f'&order_by={order_by}'
|
14
|
-
if crumbs := get_params.get('crumbs', False):
|
15
|
-
querystring += f'&crumbs={crumbs}'
|
16
|
-
for param in extra_params or []:
|
17
|
-
if value := get_params.get(param, False):
|
18
|
-
querystring += f'&{param}={value}'
|
19
|
-
return querystring
|
File without changes
|
File without changes
|