django-unfold 0.29.1__py3-none-any.whl → 0.31.0__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.
- {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>
|