django-unfold 0.29.1__py3-none-any.whl → 0.31.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- {django_unfold-0.29.1.dist-info → django_unfold-0.31.0.dist-info}/METADATA +63 -19
- {django_unfold-0.29.1.dist-info → django_unfold-0.31.0.dist-info}/RECORD +74 -73
- unfold/admin.py +32 -11
- unfold/contrib/filters/templates/unfold/filters/filters_numeric_slider.html +3 -3
- unfold/contrib/forms/static/unfold/forms/js/trix.js +2 -2
- unfold/contrib/forms/templates/unfold/forms/array.html +3 -1
- unfold/contrib/forms/templates/unfold/forms/helpers/toolbar.html +6 -6
- unfold/contrib/forms/templates/unfold/forms/wysiwyg.html +1 -1
- unfold/contrib/forms/widgets.py +22 -11
- unfold/contrib/guardian/templates/unfold/guardian/group_form.html +4 -4
- unfold/contrib/guardian/templates/unfold/guardian/user_form.html +4 -4
- unfold/contrib/import_export/templates/admin/import_export/change_form.html +1 -1
- unfold/contrib/import_export/templates/admin/import_export/import_errors.html +1 -1
- unfold/contrib/import_export/templates/admin/import_export/import_preview.html +3 -3
- unfold/contrib/import_export/templates/admin/import_export/import_validation.html +4 -4
- unfold/contrib/inlines/forms.py +1 -2
- unfold/contrib/simple_history/templates/simple_history/object_history_list.html +9 -9
- unfold/contrib/simple_history/templates/simple_history/submit_line.html +1 -1
- unfold/dataclasses.py +10 -1
- unfold/fields.py +2 -2
- unfold/forms.py +18 -3
- unfold/settings.py +1 -0
- unfold/sites.py +39 -15
- unfold/static/unfold/css/styles.css +1 -1
- unfold/static/unfold/js/alpine.anchor.js +1 -0
- unfold/static/unfold/js/alpine.js +2 -2
- unfold/static/unfold/js/alpine.persist.js +1 -1
- unfold/static/unfold/js/app.js +45 -3
- unfold/styles.css +15 -11
- unfold/templates/admin/actions.html +1 -1
- unfold/templates/admin/app_list.html +1 -1
- unfold/templates/admin/base.html +4 -4
- unfold/templates/admin/change_list.html +2 -2
- unfold/templates/admin/change_list_results.html +3 -3
- unfold/templates/admin/delete_confirmation.html +4 -4
- unfold/templates/admin/delete_selected_confirmation.html +4 -4
- unfold/templates/admin/edit_inline/stacked.html +2 -2
- unfold/templates/admin/edit_inline/tabular.html +4 -4
- unfold/templates/admin/filter.html +2 -2
- unfold/templates/admin/includes/fieldset.html +1 -1
- unfold/templates/admin/includes/object_delete_summary.html +1 -1
- unfold/templates/admin/login.html +8 -8
- unfold/templates/admin/object_history.html +4 -4
- unfold/templates/admin/search_form.html +1 -1
- unfold/templates/admin/submit_line.html +7 -5
- unfold/templates/auth/widgets/read_only_password_hash.html +1 -1
- unfold/templates/registration/logged_out.html +1 -1
- unfold/templates/unfold/change_list_filter.html +10 -2
- unfold/templates/unfold/helpers/account_links.html +2 -2
- unfold/templates/unfold/helpers/actions_row.html +4 -4
- unfold/templates/unfold/helpers/app_list.html +48 -38
- unfold/templates/unfold/helpers/app_list_default.html +4 -4
- unfold/templates/unfold/helpers/breadcrumb_item.html +1 -1
- unfold/templates/unfold/helpers/field_readonly_value.html +1 -1
- unfold/templates/unfold/helpers/fieldset_row.html +7 -7
- unfold/templates/unfold/helpers/fieldsets_tabs.html +2 -2
- unfold/templates/unfold/helpers/header.html +1 -1
- unfold/templates/unfold/helpers/help_text.html +1 -1
- unfold/templates/unfold/helpers/history.html +1 -1
- unfold/templates/unfold/helpers/label.html +1 -1
- unfold/templates/unfold/helpers/search.html +7 -4
- unfold/templates/unfold/helpers/search_results.html +2 -2
- unfold/templates/unfold/helpers/tab_action.html +1 -1
- unfold/templates/unfold/helpers/tab_list.html +27 -5
- unfold/templates/unfold/helpers/theme_switch.html +2 -2
- unfold/templates/unfold/layouts/skeleton.html +6 -1
- unfold/templates/unfold/widgets/clearable_file_input.html +14 -6
- unfold/templates/unfold/widgets/clearable_file_input_small.html +4 -4
- unfold/templates/unfold/widgets/split_datetime.html +2 -2
- unfold/templatetags/unfold.py +33 -12
- unfold/templatetags/unfold_list.py +16 -6
- unfold/widgets.py +11 -4
- {django_unfold-0.29.1.dist-info → django_unfold-0.31.0.dist-info}/LICENSE.md +0 -0
- {django_unfold-0.29.1.dist-info → django_unfold-0.31.0.dist-info}/WHEEL +0 -0
unfold/admin.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import copy
|
2
2
|
from functools import update_wrapper
|
3
|
-
from typing import Any, Callable, Dict, List, Optional, Tuple
|
3
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
4
4
|
|
5
5
|
from django import forms
|
6
6
|
from django.contrib.admin import ModelAdmin as BaseModelAdmin
|
@@ -148,6 +148,7 @@ class ModelAdminMixin:
|
|
148
148
|
else:
|
149
149
|
kwargs["widget"] = UnfoldAdminSelectWidget()
|
150
150
|
|
151
|
+
if "choices" not in kwargs:
|
151
152
|
kwargs["choices"] = db_field.get_choices(
|
152
153
|
include_blank=db_field.blank, blank_choice=[("", _("Select value"))]
|
153
154
|
)
|
@@ -227,7 +228,10 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
|
|
227
228
|
actions_submit_line = ()
|
228
229
|
custom_urls = ()
|
229
230
|
add_fieldsets = ()
|
231
|
+
list_horizontal_scrollbar_top = False
|
230
232
|
list_filter_submit = False
|
233
|
+
list_fullwidth = False
|
234
|
+
compressed_fields = False
|
231
235
|
readonly_preprocess_fields = {}
|
232
236
|
checks_class = UnfoldModelAdminChecks
|
233
237
|
|
@@ -253,7 +257,10 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
|
|
253
257
|
return super().get_fieldsets(request, obj)
|
254
258
|
|
255
259
|
def _filter_unfold_actions_by_permissions(
|
256
|
-
self,
|
260
|
+
self,
|
261
|
+
request: HttpRequest,
|
262
|
+
actions: List[UnfoldAction],
|
263
|
+
object_id: Optional[Union[int, str]] = None,
|
257
264
|
) -> List[UnfoldAction]:
|
258
265
|
"""Filter out any Unfold actions that the user doesn't have access to."""
|
259
266
|
filtered_actions = []
|
@@ -261,12 +268,22 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
|
|
261
268
|
if not hasattr(action.method, "allowed_permissions"):
|
262
269
|
filtered_actions.append(action)
|
263
270
|
continue
|
271
|
+
|
264
272
|
permission_checks = (
|
265
273
|
getattr(self, f"has_{permission}_permission")
|
266
274
|
for permission in action.method.allowed_permissions
|
267
275
|
)
|
268
|
-
|
269
|
-
|
276
|
+
|
277
|
+
if object_id:
|
278
|
+
if any(
|
279
|
+
has_permission(request, object_id)
|
280
|
+
for has_permission in permission_checks
|
281
|
+
):
|
282
|
+
filtered_actions.append(action)
|
283
|
+
else:
|
284
|
+
if any(has_permission(request) for has_permission in permission_checks):
|
285
|
+
filtered_actions.append(action)
|
286
|
+
|
270
287
|
return filtered_actions
|
271
288
|
|
272
289
|
def get_actions_list(self, request: HttpRequest) -> List[UnfoldAction]:
|
@@ -280,9 +297,11 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
|
|
280
297
|
"""
|
281
298
|
return [self.get_unfold_action(action) for action in self.actions_list or []]
|
282
299
|
|
283
|
-
def get_actions_detail(
|
300
|
+
def get_actions_detail(
|
301
|
+
self, request: HttpRequest, object_id: int
|
302
|
+
) -> List[UnfoldAction]:
|
284
303
|
return self._filter_unfold_actions_by_permissions(
|
285
|
-
request, self._get_base_actions_detail()
|
304
|
+
request, self._get_base_actions_detail(), object_id
|
286
305
|
)
|
287
306
|
|
288
307
|
def _get_base_actions_detail(self) -> List[UnfoldAction]:
|
@@ -302,9 +321,11 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
|
|
302
321
|
"""
|
303
322
|
return [self.get_unfold_action(action) for action in self.actions_row or []]
|
304
323
|
|
305
|
-
def get_actions_submit_line(
|
324
|
+
def get_actions_submit_line(
|
325
|
+
self, request: HttpRequest, object_id: int
|
326
|
+
) -> List[UnfoldAction]:
|
306
327
|
return self._filter_unfold_actions_by_permissions(
|
307
|
-
request, self._get_base_actions_submit_line()
|
328
|
+
request, self._get_base_actions_submit_line(), object_id
|
308
329
|
)
|
309
330
|
|
310
331
|
def _get_base_actions_submit_line(self) -> List[UnfoldAction]:
|
@@ -402,7 +423,7 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
|
|
402
423
|
|
403
424
|
actions = []
|
404
425
|
if object_id:
|
405
|
-
for action in self.get_actions_detail(request):
|
426
|
+
for action in self.get_actions_detail(request, object_id):
|
406
427
|
actions.append(
|
407
428
|
{
|
408
429
|
"title": action.description,
|
@@ -416,7 +437,7 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
|
|
416
437
|
|
417
438
|
extra_context.update(
|
418
439
|
{
|
419
|
-
"actions_submit_line": self.get_actions_submit_line(request),
|
440
|
+
"actions_submit_line": self.get_actions_submit_line(request, object_id),
|
420
441
|
"actions_detail": actions,
|
421
442
|
}
|
422
443
|
)
|
@@ -483,7 +504,7 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
|
|
483
504
|
) -> None:
|
484
505
|
super().save_model(request, obj, form, change)
|
485
506
|
|
486
|
-
for action in self.get_actions_submit_line(request):
|
507
|
+
for action in self.get_actions_submit_line(request, obj.pk):
|
487
508
|
if action.action_name not in request.POST:
|
488
509
|
continue
|
489
510
|
|
@@ -9,11 +9,11 @@
|
|
9
9
|
|
10
10
|
{% if choice.min is not None and choice.max is not None and choice.step %}
|
11
11
|
<div class="admin-numeric-filter-slider-tooltips">
|
12
|
-
<span class="admin-numeric-filter-slider-tooltip-from border cursor-not-allowed flex flex-grow flex-row items-center mr-auto rounded-md shadow-sm px-3 py-2 w-full dark:bg-gray-900 dark:border-gray-700 dark:text-gray-
|
12
|
+
<span class="admin-numeric-filter-slider-tooltip-from border cursor-not-allowed flex flex-grow flex-row items-center mr-auto rounded-md shadow-sm px-3 py-2 w-full dark:bg-gray-900 dark:border-gray-700 dark:text-gray-300">
|
13
13
|
{{ choice.value_from }}
|
14
14
|
</span>
|
15
15
|
|
16
|
-
<span class="admin-numeric-filter-slider-tooltip-to border cursor-not-allowed flex flex-grow flex-row items-center rounded-md shadow-sm px-3 py-2 w-full dark:bg-gray-900 dark:border-gray-700 dark:text-gray-
|
16
|
+
<span class="admin-numeric-filter-slider-tooltip-to border cursor-not-allowed flex flex-grow flex-row items-center rounded-md shadow-sm px-3 py-2 w-full dark:bg-gray-900 dark:border-gray-700 dark:text-gray-300">
|
17
17
|
{{ choice.value_to }}
|
18
18
|
</span>
|
19
19
|
</div>
|
@@ -25,7 +25,7 @@
|
|
25
25
|
{{ choice.form.as_p }}
|
26
26
|
</div>
|
27
27
|
{% else %}
|
28
|
-
<div class="admin-numeric-filter-slider-error dark:text-gray-
|
28
|
+
<div class="admin-numeric-filter-slider-error dark:text-gray-300">
|
29
29
|
<p>
|
30
30
|
{% trans 'Not enough data.' %}
|
31
31
|
</p>
|