django-smartbase-admin 1.0.12__py3-none-any.whl → 1.0.14__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_smartbase_admin/admin/admin_base.py +19 -17
- django_smartbase_admin/admin/widgets.py +10 -9
- django_smartbase_admin/engine/admin_base_view.py +46 -22
- django_smartbase_admin/engine/configuration.py +25 -25
- django_smartbase_admin/engine/const.py +1 -0
- django_smartbase_admin/engine/menu_item.py +8 -5
- django_smartbase_admin/static/sb_admin/dist/main.js +1 -1
- django_smartbase_admin/static/sb_admin/dist/main_style.css +1 -1
- django_smartbase_admin/static/sb_admin/images/file_types/file-csv.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-doc.svg +1 -1
- django_smartbase_admin/static/sb_admin/images/file_types/file-docx.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-other.svg +13 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-pdf.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-ppt.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-xls.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-xlsx.svg +1 -1
- django_smartbase_admin/static/sb_admin/images/file_types/file-zip.svg +18 -0
- django_smartbase_admin/static/sb_admin/src/css/components/_input.css +3 -0
- django_smartbase_admin/static/sb_admin/src/js/main.js +13 -1
- django_smartbase_admin/static/sb_admin/src/js/multiselect.js +4 -2
- django_smartbase_admin/templates/sb_admin/actions/change_form.html +25 -23
- django_smartbase_admin/templates/sb_admin/includes/inline_fieldset.html +11 -11
- django_smartbase_admin/templates/sb_admin/widgets/clearable_file_input.html +1 -1
- django_smartbase_admin/templatetags/sb_admin_tags.py +9 -11
- django_smartbase_admin/utils.py +4 -1
- django_smartbase_admin/views/translations_view.py +9 -3
- {django_smartbase_admin-1.0.12.dist-info → django_smartbase_admin-1.0.14.dist-info}/METADATA +1 -1
- {django_smartbase_admin-1.0.12.dist-info → django_smartbase_admin-1.0.14.dist-info}/RECORD +30 -23
- {django_smartbase_admin-1.0.12.dist-info → django_smartbase_admin-1.0.14.dist-info}/LICENSE.md +0 -0
- {django_smartbase_admin-1.0.12.dist-info → django_smartbase_admin-1.0.14.dist-info}/WHEEL +0 -0
|
@@ -36,6 +36,8 @@ from django.utils.text import capfirst
|
|
|
36
36
|
from django.utils.translation import gettext_lazy as _
|
|
37
37
|
from django_admin_inline_paginator.admin import TabularInlinePaginated
|
|
38
38
|
from django_htmx.http import trigger_client_event
|
|
39
|
+
from parler.admin import TranslatableAdmin
|
|
40
|
+
|
|
39
41
|
from django_smartbase_admin.engine.field import SBAdminField
|
|
40
42
|
from filer.fields.file import FilerFileField
|
|
41
43
|
from filer.fields.image import AdminImageFormField, FilerImageField
|
|
@@ -821,6 +823,9 @@ class SBAdmin(
|
|
|
821
823
|
def get_additional_filter_for_previous_next_context(self, request, object_id) -> Q:
|
|
822
824
|
return Q()
|
|
823
825
|
|
|
826
|
+
def get_change_view_context(self, request, object_id) -> dict | dict[str, Any]:
|
|
827
|
+
return {"show_back_button": True}
|
|
828
|
+
|
|
824
829
|
def get_previous_next_context(self, request, object_id) -> dict | dict[str, Any]:
|
|
825
830
|
if not self.sbadmin_previous_next_buttons_enabled or not object_id:
|
|
826
831
|
return {}
|
|
@@ -871,6 +876,7 @@ class SBAdmin(
|
|
|
871
876
|
|
|
872
877
|
def change_view(self, request, object_id, form_url="", extra_context=None):
|
|
873
878
|
extra_context = extra_context or {}
|
|
879
|
+
extra_context.update(self.get_change_view_context(request, object_id))
|
|
874
880
|
extra_context.update(self.get_global_context(request, object_id))
|
|
875
881
|
extra_context.update(self.get_fieldsets_context(request, object_id))
|
|
876
882
|
extra_context.update(self.get_tabs_context(request, object_id))
|
|
@@ -990,23 +996,6 @@ class SBAdmin(
|
|
|
990
996
|
self.set_generic_relation_from_parent(request, obj)
|
|
991
997
|
super().save_model(request, obj, form, change)
|
|
992
998
|
|
|
993
|
-
def process_field_data(
|
|
994
|
-
self,
|
|
995
|
-
request,
|
|
996
|
-
field: SBAdminField,
|
|
997
|
-
obj_id: Any,
|
|
998
|
-
value: Any,
|
|
999
|
-
additional_data: dict[str, Any],
|
|
1000
|
-
) -> Any:
|
|
1001
|
-
is_xlsx_export = request.request_data.action == Action.XLSX_EXPORT.value
|
|
1002
|
-
if field.view_method:
|
|
1003
|
-
value = field.view_method(obj_id, value, **additional_data)
|
|
1004
|
-
if is_xlsx_export and getattr(field.xlsx_options, "python_formatter", None):
|
|
1005
|
-
value = field.xlsx_options.python_formatter(obj_id, value)
|
|
1006
|
-
elif field.python_formatter:
|
|
1007
|
-
value = field.python_formatter(obj_id, value)
|
|
1008
|
-
return value
|
|
1009
|
-
|
|
1010
999
|
|
|
1011
1000
|
class SBAdminInline(
|
|
1012
1001
|
SBAdminInlineAndAdminCommon, SBAdminBaseQuerysetMixin, SBAdminBaseView
|
|
@@ -1168,3 +1157,16 @@ class SBAdminStackedInline(SBAdminInline, NestedStackedInline):
|
|
|
1168
1157
|
class SBAdminGenericStackedInline(SBAdminInline, NestedGenericStackedInline):
|
|
1169
1158
|
template = "sb_admin/inlines/stacked_inline.html"
|
|
1170
1159
|
fieldset_template = "sb_admin/includes/inline_fieldset.html"
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
class SBTranslatableAdmin(SBAdmin, TranslatableAdmin):
|
|
1163
|
+
def get_readonly_fields(self, request, obj=...):
|
|
1164
|
+
readonly_fields = super().get_readonly_fields(request, obj)
|
|
1165
|
+
if "sbadmin_translation_status" not in readonly_fields:
|
|
1166
|
+
readonly_fields += ("sbadmin_translation_status",)
|
|
1167
|
+
return readonly_fields
|
|
1168
|
+
|
|
1169
|
+
def get_fieldsets(self, request, obj=...):
|
|
1170
|
+
fieldsets = super().get_fieldsets(request, obj)
|
|
1171
|
+
fieldsets.append(SBAdminTranslationsService.get_translation_fieldset())
|
|
1172
|
+
return fieldsets
|
|
@@ -82,9 +82,10 @@ class SBAdminBaseWidget(ContextMixin):
|
|
|
82
82
|
)
|
|
83
83
|
except:
|
|
84
84
|
pass
|
|
85
|
-
context[
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
widget_id = f"{modal_prefix}{opts.app_label}_{opts.model_name}_{context['widget']['attrs']['id']}"
|
|
86
|
+
context["widget"]["attrs"]["id"] = widget_id
|
|
87
|
+
# needed for BoundField.id_for_label to work correctly
|
|
88
|
+
self.attrs["id"] = widget_id
|
|
88
89
|
return context
|
|
89
90
|
|
|
90
91
|
|
|
@@ -420,25 +421,25 @@ class SBAdminAutocompleteWidget(
|
|
|
420
421
|
)
|
|
421
422
|
and not self.is_multiselect()
|
|
422
423
|
):
|
|
423
|
-
self.add_related_buttons_urls(parsed_value, context)
|
|
424
|
+
self.add_related_buttons_urls(parsed_value, threadsafe_request, context)
|
|
424
425
|
|
|
425
426
|
return context
|
|
426
427
|
|
|
427
|
-
def add_related_buttons_urls(self, parsed_value, context):
|
|
428
|
+
def add_related_buttons_urls(self, parsed_value, request, context):
|
|
428
429
|
related_model = self.model
|
|
429
430
|
app_label = related_model._meta.app_label
|
|
430
431
|
model_name = related_model._meta.model_name
|
|
431
432
|
|
|
432
433
|
try:
|
|
433
|
-
if parsed_value:
|
|
434
|
+
if parsed_value and self.has_view_or_change_permission(request, self.model):
|
|
434
435
|
change_url = reverse(
|
|
435
436
|
"sb_admin:{}_{}_change".format(app_label, model_name),
|
|
436
437
|
args=(parsed_value,),
|
|
437
438
|
)
|
|
438
439
|
context["widget"]["attrs"]["related_edit_url"] = change_url
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
440
|
+
if self.has_add_permission(request, self.model):
|
|
441
|
+
add_url = reverse("sb_admin:{}_{}_add".format(app_label, model_name))
|
|
442
|
+
context["widget"]["attrs"]["related_add_url"] = add_url
|
|
442
443
|
except NoReverseMatch:
|
|
443
444
|
pass
|
|
444
445
|
|
|
@@ -2,7 +2,7 @@ import json
|
|
|
2
2
|
import urllib.parse
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
from collections.abc import Iterable
|
|
5
|
-
from typing import Any
|
|
5
|
+
from typing import Any, TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
from django.contrib import messages
|
|
8
8
|
from django.contrib.admin.actions import delete_selected
|
|
@@ -11,6 +11,7 @@ from django.db.models import F
|
|
|
11
11
|
from django.http import HttpResponse, Http404, JsonResponse
|
|
12
12
|
from django.shortcuts import redirect
|
|
13
13
|
from django.template.response import TemplateResponse
|
|
14
|
+
from django.templatetags.static import static
|
|
14
15
|
from django.urls import reverse
|
|
15
16
|
from django.utils.translation import gettext_lazy as _
|
|
16
17
|
|
|
@@ -35,6 +36,7 @@ from django_smartbase_admin.engine.const import (
|
|
|
35
36
|
TABLE_UPDATE_ROW_DATA_EVENT_NAME,
|
|
36
37
|
SELECT_ALL_KEYWORD,
|
|
37
38
|
IGNORE_LIST_SELECTION,
|
|
39
|
+
SUPPORTED_FILE_TYPE_ICONS,
|
|
38
40
|
)
|
|
39
41
|
from django_smartbase_admin.services.views import SBAdminViewService
|
|
40
42
|
from django_smartbase_admin.services.xlsx_export import (
|
|
@@ -44,6 +46,9 @@ from django_smartbase_admin.services.xlsx_export import (
|
|
|
44
46
|
)
|
|
45
47
|
from django_smartbase_admin.utils import is_htmx_request, render_notifications, is_modal
|
|
46
48
|
|
|
49
|
+
if TYPE_CHECKING:
|
|
50
|
+
from django_smartbase_admin.engine.field import SBAdminField
|
|
51
|
+
|
|
47
52
|
SBADMIN_IS_MODAL_VAR = "sbadmin_is_modal"
|
|
48
53
|
SBADMIN_PARENT_INSTANCE_FIELD_NAME_VAR = "sbadmin_parent_instance_field"
|
|
49
54
|
SBADMIN_PARENT_INSTANCE_PK_VAR = "sbadmin_parent_instance_pk"
|
|
@@ -103,7 +108,7 @@ class SBAdminBaseView(object):
|
|
|
103
108
|
return inner_view
|
|
104
109
|
|
|
105
110
|
def process_actions(
|
|
106
|
-
|
|
111
|
+
self, request, actions: list[SBAdminCustomAction]
|
|
107
112
|
) -> list[SBAdminCustomAction]:
|
|
108
113
|
processed_actions = self.process_actions_permissions(request, actions)
|
|
109
114
|
for processed_action in processed_actions:
|
|
@@ -120,7 +125,7 @@ class SBAdminBaseView(object):
|
|
|
120
125
|
return processed_actions
|
|
121
126
|
|
|
122
127
|
def process_actions_permissions(
|
|
123
|
-
|
|
128
|
+
self, request, actions: list[SBAdminCustomAction]
|
|
124
129
|
) -> list[SBAdminCustomAction]:
|
|
125
130
|
result = []
|
|
126
131
|
for action in actions:
|
|
@@ -199,12 +204,12 @@ class SBAdminBaseView(object):
|
|
|
199
204
|
}
|
|
200
205
|
|
|
201
206
|
def get_sbadmin_detail_actions(
|
|
202
|
-
|
|
207
|
+
self, request, object_id: int | str | None = None
|
|
203
208
|
) -> Iterable[SBAdminCustomAction] | None:
|
|
204
209
|
return self.sbadmin_detail_actions
|
|
205
210
|
|
|
206
211
|
def get_global_context(
|
|
207
|
-
|
|
212
|
+
self, request, object_id: int | str | None = None
|
|
208
213
|
) -> dict[str, Any]:
|
|
209
214
|
return {
|
|
210
215
|
"view_id": self.get_id(),
|
|
@@ -216,7 +221,7 @@ class SBAdminBaseView(object):
|
|
|
216
221
|
"detail_actions": self.get_sbadmin_detail_actions(request, object_id),
|
|
217
222
|
SBADMIN_IS_MODAL_VAR: is_modal(request),
|
|
218
223
|
SBADMIN_RELOAD_ON_SAVE_VAR: SBADMIN_RELOAD_ON_SAVE_VAR in request.GET
|
|
219
|
-
|
|
224
|
+
or SBADMIN_RELOAD_ON_SAVE_VAR in request.POST,
|
|
220
225
|
"const": json.dumps(
|
|
221
226
|
{
|
|
222
227
|
"MULTISELECT_FILTER_MAX_CHOICES_SHOWN": MULTISELECT_FILTER_MAX_CHOICES_SHOWN,
|
|
@@ -225,6 +230,8 @@ class SBAdminBaseView(object):
|
|
|
225
230
|
"TABLE_RELOAD_DATA_EVENT_NAME": TABLE_RELOAD_DATA_EVENT_NAME,
|
|
226
231
|
"TABLE_UPDATE_ROW_DATA_EVENT_NAME": TABLE_UPDATE_ROW_DATA_EVENT_NAME,
|
|
227
232
|
"SELECT_ALL_KEYWORD": SELECT_ALL_KEYWORD,
|
|
233
|
+
"SUPPORTED_FILE_TYPE_ICONS": SUPPORTED_FILE_TYPE_ICONS,
|
|
234
|
+
"STATIC_BASE_PATH": static("sb_admin"),
|
|
228
235
|
}
|
|
229
236
|
),
|
|
230
237
|
}
|
|
@@ -232,6 +239,23 @@ class SBAdminBaseView(object):
|
|
|
232
239
|
def get_model_path(self) -> str:
|
|
233
240
|
return SBAdminViewService.get_model_path(self.model)
|
|
234
241
|
|
|
242
|
+
def process_field_data(
|
|
243
|
+
self,
|
|
244
|
+
request,
|
|
245
|
+
field: "SBAdminField",
|
|
246
|
+
obj_id: Any,
|
|
247
|
+
value: Any,
|
|
248
|
+
additional_data: dict[str, Any],
|
|
249
|
+
) -> Any:
|
|
250
|
+
is_xlsx_export = request.request_data.action == Action.XLSX_EXPORT.value
|
|
251
|
+
if field.view_method:
|
|
252
|
+
value = field.view_method(obj_id, value, **additional_data)
|
|
253
|
+
if is_xlsx_export and getattr(field.xlsx_options, "python_formatter", None):
|
|
254
|
+
value = field.xlsx_options.python_formatter(obj_id, value)
|
|
255
|
+
elif field.python_formatter:
|
|
256
|
+
value = field.python_formatter(obj_id, value)
|
|
257
|
+
return value
|
|
258
|
+
|
|
235
259
|
|
|
236
260
|
class SBAdminBaseQuerysetMixin(object):
|
|
237
261
|
def get_queryset(self, request=None):
|
|
@@ -298,8 +322,8 @@ class SBAdminBaseListView(SBAdminBaseView):
|
|
|
298
322
|
|
|
299
323
|
def is_reorder_active(self, request) -> bool:
|
|
300
324
|
return (
|
|
301
|
-
|
|
302
|
-
|
|
325
|
+
self.is_reorder_available(request)
|
|
326
|
+
and getattr(request, "reorder_active", False) == True
|
|
303
327
|
)
|
|
304
328
|
|
|
305
329
|
def is_reorder_available(self, request) -> str | None:
|
|
@@ -334,7 +358,7 @@ class SBAdminBaseListView(SBAdminBaseView):
|
|
|
334
358
|
qs.filter(**{f"{pk_field}__in": item_ids}).update(
|
|
335
359
|
**{
|
|
336
360
|
self.sbadmin_list_reorder_field: F(self.sbadmin_list_reorder_field)
|
|
337
|
-
|
|
361
|
+
+ int(diff)
|
|
338
362
|
}
|
|
339
363
|
)
|
|
340
364
|
return JsonResponse({"message": request.POST})
|
|
@@ -514,7 +538,7 @@ class SBAdminBaseListView(SBAdminBaseView):
|
|
|
514
538
|
return self.sbadmin_list_selection_actions
|
|
515
539
|
|
|
516
540
|
def get_sbadmin_list_selection_actions_grouped(
|
|
517
|
-
|
|
541
|
+
self, request
|
|
518
542
|
) -> dict[str, list[SBAdminCustomAction]]:
|
|
519
543
|
result = {}
|
|
520
544
|
list_selection_actions = self.process_actions(
|
|
@@ -546,8 +570,8 @@ class SBAdminBaseListView(SBAdminBaseView):
|
|
|
546
570
|
def action_bulk_delete(self, request, modifier):
|
|
547
571
|
action = self.sbadmin_list_action_class(self, request)
|
|
548
572
|
if (
|
|
549
|
-
|
|
550
|
-
|
|
573
|
+
request.request_data.request_method == "POST"
|
|
574
|
+
and request.headers.get("X-TabulatorRequest", None) == "true"
|
|
551
575
|
):
|
|
552
576
|
return redirect(
|
|
553
577
|
self.get_action_url("action_bulk_delete")
|
|
@@ -625,13 +649,13 @@ class SBAdminBaseListView(SBAdminBaseView):
|
|
|
625
649
|
return redirect_to
|
|
626
650
|
|
|
627
651
|
def action_list(
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
652
|
+
self,
|
|
653
|
+
request,
|
|
654
|
+
page_size=None,
|
|
655
|
+
tabulator_definition=None,
|
|
656
|
+
extra_context=None,
|
|
657
|
+
list_actions=None,
|
|
658
|
+
template=None,
|
|
635
659
|
):
|
|
636
660
|
action = self.sbadmin_list_action_class(
|
|
637
661
|
self,
|
|
@@ -684,8 +708,8 @@ class SBAdminBaseListView(SBAdminBaseView):
|
|
|
684
708
|
getattr(field, "filter_field", field): ""
|
|
685
709
|
for field in list_fields
|
|
686
710
|
if field in list_filter
|
|
687
|
-
|
|
688
|
-
|
|
711
|
+
or getattr(field, "name", None) in list_filter
|
|
712
|
+
or getattr(field, "filter_field", None) in list_filter
|
|
689
713
|
}
|
|
690
714
|
url_params = None
|
|
691
715
|
if base_filter:
|
|
@@ -760,7 +784,7 @@ class SBAdminBaseListView(SBAdminBaseView):
|
|
|
760
784
|
|
|
761
785
|
def get_filters_version(self, request) -> FilterVersions:
|
|
762
786
|
return (
|
|
763
|
-
|
|
787
|
+
self.filters_version or request.request_data.configuration.filters_version
|
|
764
788
|
)
|
|
765
789
|
|
|
766
790
|
def get_filters_template_name(self, request) -> str:
|
|
@@ -41,12 +41,12 @@ class SBAdminRoleConfiguration(metaclass=Singleton):
|
|
|
41
41
|
filters_version = FilterVersions.FILTERS_VERSION_1
|
|
42
42
|
|
|
43
43
|
def __init__(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
self,
|
|
45
|
+
default_view=None,
|
|
46
|
+
registered_views=None,
|
|
47
|
+
menu_items=None,
|
|
48
|
+
global_filter_form=None,
|
|
49
|
+
filters_version=None,
|
|
50
50
|
) -> None:
|
|
51
51
|
super().__init__()
|
|
52
52
|
self.default_view = default_view or self.default_view or []
|
|
@@ -134,13 +134,13 @@ class SBAdminRoleConfiguration(metaclass=Singleton):
|
|
|
134
134
|
self.autocomplete_map[view.get_id()] = view
|
|
135
135
|
|
|
136
136
|
def restrict_queryset(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
137
|
+
self,
|
|
138
|
+
qs,
|
|
139
|
+
model,
|
|
140
|
+
request,
|
|
141
|
+
request_data,
|
|
142
|
+
global_filter=True,
|
|
143
|
+
global_filter_data_map=None,
|
|
144
144
|
):
|
|
145
145
|
return qs
|
|
146
146
|
|
|
@@ -154,7 +154,7 @@ class SBAdminRoleConfiguration(metaclass=Singleton):
|
|
|
154
154
|
return request.user.is_staff
|
|
155
155
|
|
|
156
156
|
def has_permission(
|
|
157
|
-
|
|
157
|
+
self, request, request_data, view, model=None, obj=None, permission=None
|
|
158
158
|
):
|
|
159
159
|
if isinstance(permission, SBAdminCustomAction):
|
|
160
160
|
return self.has_action_permission(
|
|
@@ -174,7 +174,7 @@ class SBAdminRoleConfiguration(metaclass=Singleton):
|
|
|
174
174
|
return request.user.is_staff
|
|
175
175
|
|
|
176
176
|
def get_autocomplete_widget(
|
|
177
|
-
|
|
177
|
+
self, view, request, form_field, db_field, model, multiselect=False
|
|
178
178
|
):
|
|
179
179
|
from django_smartbase_admin.admin.widgets import SBAdminAutocompleteWidget
|
|
180
180
|
|
|
@@ -186,12 +186,12 @@ class SBAdminRoleConfiguration(metaclass=Singleton):
|
|
|
186
186
|
return default_widget
|
|
187
187
|
|
|
188
188
|
def get_form_field_widget_class(
|
|
189
|
-
|
|
189
|
+
self, view, request, form_field, db_field, default_widget_class
|
|
190
190
|
):
|
|
191
191
|
return default_widget_class
|
|
192
192
|
|
|
193
193
|
def apply_global_filter_to_queryset(
|
|
194
|
-
|
|
194
|
+
self, qs, request, request_data, global_filter_data_map
|
|
195
195
|
):
|
|
196
196
|
global_filter_data_map = global_filter_data_map or {}
|
|
197
197
|
global_filter_data_map = {
|
|
@@ -211,9 +211,9 @@ class SBAdminRoleConfiguration(metaclass=Singleton):
|
|
|
211
211
|
except:
|
|
212
212
|
pass
|
|
213
213
|
if (
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
214
|
+
include_all_values_for_empty_fields
|
|
215
|
+
and field.name in include_all_values_for_empty_fields
|
|
216
|
+
and not field_value
|
|
217
217
|
):
|
|
218
218
|
continue
|
|
219
219
|
field_value = to_list(field_value)
|
|
@@ -228,10 +228,10 @@ class SBAdminRoleConfiguration(metaclass=Singleton):
|
|
|
228
228
|
return response
|
|
229
229
|
|
|
230
230
|
def autocomplete_show_related_buttons(
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
231
|
+
self,
|
|
232
|
+
related_model,
|
|
233
|
+
field_name,
|
|
234
|
+
current_view,
|
|
235
|
+
request,
|
|
236
236
|
) -> bool:
|
|
237
237
|
return not is_modal(request)
|
|
@@ -74,3 +74,4 @@ TRANSLATIONS_SELECTED_LANGUAGES = "translation_selected_languages"
|
|
|
74
74
|
OVERRIDE_CONTENT_OF_NOTIFICATION = "override_notification_content"
|
|
75
75
|
FIELDSET_HIDE_HEADER_CLASS = "hide-header"
|
|
76
76
|
ROW_CLASS_FIELD = "get_sbadmin_row_class"
|
|
77
|
+
SUPPORTED_FILE_TYPE_ICONS = ["doc", "docx", "csv", "xls", "xlsx", "pdf", "ppt", "zip"]
|
|
@@ -56,11 +56,14 @@ class SBAdminMenuItem(object):
|
|
|
56
56
|
return self.label or self.view.get_menu_label()
|
|
57
57
|
|
|
58
58
|
def get_url(self, request):
|
|
59
|
-
|
|
60
|
-
self.url
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
if callable(self.url):
|
|
60
|
+
return self.url(request)
|
|
61
|
+
elif self.url:
|
|
62
|
+
return self.url
|
|
63
|
+
elif self.view:
|
|
64
|
+
return self.view.get_menu_view_url(request)
|
|
65
|
+
else:
|
|
66
|
+
return ""
|
|
64
67
|
|
|
65
68
|
def get_icon(self):
|
|
66
69
|
return self.icon or getattr(self.view, "icon", None)
|