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.
Files changed (74) hide show
  1. {django_unfold-0.29.1.dist-info → django_unfold-0.31.0.dist-info}/METADATA +63 -19
  2. {django_unfold-0.29.1.dist-info → django_unfold-0.31.0.dist-info}/RECORD +74 -73
  3. unfold/admin.py +32 -11
  4. unfold/contrib/filters/templates/unfold/filters/filters_numeric_slider.html +3 -3
  5. unfold/contrib/forms/static/unfold/forms/js/trix.js +2 -2
  6. unfold/contrib/forms/templates/unfold/forms/array.html +3 -1
  7. unfold/contrib/forms/templates/unfold/forms/helpers/toolbar.html +6 -6
  8. unfold/contrib/forms/templates/unfold/forms/wysiwyg.html +1 -1
  9. unfold/contrib/forms/widgets.py +22 -11
  10. unfold/contrib/guardian/templates/unfold/guardian/group_form.html +4 -4
  11. unfold/contrib/guardian/templates/unfold/guardian/user_form.html +4 -4
  12. unfold/contrib/import_export/templates/admin/import_export/change_form.html +1 -1
  13. unfold/contrib/import_export/templates/admin/import_export/import_errors.html +1 -1
  14. unfold/contrib/import_export/templates/admin/import_export/import_preview.html +3 -3
  15. unfold/contrib/import_export/templates/admin/import_export/import_validation.html +4 -4
  16. unfold/contrib/inlines/forms.py +1 -2
  17. unfold/contrib/simple_history/templates/simple_history/object_history_list.html +9 -9
  18. unfold/contrib/simple_history/templates/simple_history/submit_line.html +1 -1
  19. unfold/dataclasses.py +10 -1
  20. unfold/fields.py +2 -2
  21. unfold/forms.py +18 -3
  22. unfold/settings.py +1 -0
  23. unfold/sites.py +39 -15
  24. unfold/static/unfold/css/styles.css +1 -1
  25. unfold/static/unfold/js/alpine.anchor.js +1 -0
  26. unfold/static/unfold/js/alpine.js +2 -2
  27. unfold/static/unfold/js/alpine.persist.js +1 -1
  28. unfold/static/unfold/js/app.js +45 -3
  29. unfold/styles.css +15 -11
  30. unfold/templates/admin/actions.html +1 -1
  31. unfold/templates/admin/app_list.html +1 -1
  32. unfold/templates/admin/base.html +4 -4
  33. unfold/templates/admin/change_list.html +2 -2
  34. unfold/templates/admin/change_list_results.html +3 -3
  35. unfold/templates/admin/delete_confirmation.html +4 -4
  36. unfold/templates/admin/delete_selected_confirmation.html +4 -4
  37. unfold/templates/admin/edit_inline/stacked.html +2 -2
  38. unfold/templates/admin/edit_inline/tabular.html +4 -4
  39. unfold/templates/admin/filter.html +2 -2
  40. unfold/templates/admin/includes/fieldset.html +1 -1
  41. unfold/templates/admin/includes/object_delete_summary.html +1 -1
  42. unfold/templates/admin/login.html +8 -8
  43. unfold/templates/admin/object_history.html +4 -4
  44. unfold/templates/admin/search_form.html +1 -1
  45. unfold/templates/admin/submit_line.html +7 -5
  46. unfold/templates/auth/widgets/read_only_password_hash.html +1 -1
  47. unfold/templates/registration/logged_out.html +1 -1
  48. unfold/templates/unfold/change_list_filter.html +10 -2
  49. unfold/templates/unfold/helpers/account_links.html +2 -2
  50. unfold/templates/unfold/helpers/actions_row.html +4 -4
  51. unfold/templates/unfold/helpers/app_list.html +48 -38
  52. unfold/templates/unfold/helpers/app_list_default.html +4 -4
  53. unfold/templates/unfold/helpers/breadcrumb_item.html +1 -1
  54. unfold/templates/unfold/helpers/field_readonly_value.html +1 -1
  55. unfold/templates/unfold/helpers/fieldset_row.html +7 -7
  56. unfold/templates/unfold/helpers/fieldsets_tabs.html +2 -2
  57. unfold/templates/unfold/helpers/header.html +1 -1
  58. unfold/templates/unfold/helpers/help_text.html +1 -1
  59. unfold/templates/unfold/helpers/history.html +1 -1
  60. unfold/templates/unfold/helpers/label.html +1 -1
  61. unfold/templates/unfold/helpers/search.html +7 -4
  62. unfold/templates/unfold/helpers/search_results.html +2 -2
  63. unfold/templates/unfold/helpers/tab_action.html +1 -1
  64. unfold/templates/unfold/helpers/tab_list.html +27 -5
  65. unfold/templates/unfold/helpers/theme_switch.html +2 -2
  66. unfold/templates/unfold/layouts/skeleton.html +6 -1
  67. unfold/templates/unfold/widgets/clearable_file_input.html +14 -6
  68. unfold/templates/unfold/widgets/clearable_file_input_small.html +4 -4
  69. unfold/templates/unfold/widgets/split_datetime.html +2 -2
  70. unfold/templatetags/unfold.py +33 -12
  71. unfold/templatetags/unfold_list.py +16 -6
  72. unfold/widgets.py +11 -4
  73. {django_unfold-0.29.1.dist-info → django_unfold-0.31.0.dist-info}/LICENSE.md +0 -0
  74. {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, request: HttpRequest, actions: List[UnfoldAction]
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
- if any(has_permission(request) for has_permission in permission_checks):
269
- filtered_actions.append(action)
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(self, request: HttpRequest) -> List[UnfoldAction]:
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(self, request: HttpRequest) -> List[UnfoldAction]:
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-400">
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-400">
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-400">
28
+ <div class="admin-numeric-filter-slider-error dark:text-gray-300">
29
29
  <p>
30
30
  {% trans 'Not enough data.' %}
31
31
  </p>