|
@@ -166,6 +166,7 @@ class ActionsItem:
|
|
|
title: str
|
|
title: str
|
|
|
icon: str
|
|
icon: str
|
|
|
permission: Optional[str] = None
|
|
permission: Optional[str] = None
|
|
|
|
|
+ css_class: Optional[str] = 'secondary'
|
|
|
|
|
|
|
|
|
|
|
|
|
class ActionsColumn(tables.Column):
|
|
class ActionsColumn(tables.Column):
|
|
@@ -175,13 +176,14 @@ class ActionsColumn(tables.Column):
|
|
|
|
|
|
|
|
:param actions: The ordered list of dropdown menu items to include
|
|
:param actions: The ordered list of dropdown menu items to include
|
|
|
:param extra_buttons: A Django template string which renders additional buttons preceding the actions dropdown
|
|
:param extra_buttons: A Django template string which renders additional buttons preceding the actions dropdown
|
|
|
- :param split_actions: When True, converts the actions dropdown menu into a split button with first action as the direct button link and icon (default: True)
|
|
|
|
|
|
|
+ :param split_actions: When True, converts the actions dropdown menu into a split button with first action as the
|
|
|
|
|
+ direct button link and icon (default: True)
|
|
|
"""
|
|
"""
|
|
|
attrs = {'td': {'class': 'text-end text-nowrap noprint'}}
|
|
attrs = {'td': {'class': 'text-end text-nowrap noprint'}}
|
|
|
empty_values = ()
|
|
empty_values = ()
|
|
|
actions = {
|
|
actions = {
|
|
|
- 'edit': ActionsItem('Edit', 'pencil', 'change'),
|
|
|
|
|
- 'delete': ActionsItem('Delete', 'trash-can-outline', 'delete'),
|
|
|
|
|
|
|
+ 'edit': ActionsItem('Edit', 'pencil', 'change', 'warning'),
|
|
|
|
|
+ 'delete': ActionsItem('Delete', 'trash-can-outline', 'delete', 'danger'),
|
|
|
'changelog': ActionsItem('Changelog', 'history'),
|
|
'changelog': ActionsItem('Changelog', 'history'),
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -210,45 +212,49 @@ class ActionsColumn(tables.Column):
|
|
|
html = ''
|
|
html = ''
|
|
|
|
|
|
|
|
# Compile actions menu
|
|
# Compile actions menu
|
|
|
- links = []
|
|
|
|
|
|
|
+ button = None
|
|
|
|
|
+ dropdown_class = 'secondary'
|
|
|
|
|
+ dropdown_links = []
|
|
|
user = getattr(request, 'user', AnonymousUser())
|
|
user = getattr(request, 'user', AnonymousUser())
|
|
|
for idx, (action, attrs) in enumerate(self.actions.items()):
|
|
for idx, (action, attrs) in enumerate(self.actions.items()):
|
|
|
permission = f'{model._meta.app_label}.{attrs.permission}_{model._meta.model_name}'
|
|
permission = f'{model._meta.app_label}.{attrs.permission}_{model._meta.model_name}'
|
|
|
if attrs.permission is None or user.has_perm(permission):
|
|
if attrs.permission is None or user.has_perm(permission):
|
|
|
url = reverse(get_viewname(model, action), kwargs={'pk': record.pk})
|
|
url = reverse(get_viewname(model, action), kwargs={'pk': record.pk})
|
|
|
|
|
|
|
|
- # If only a single action exists, render a regular button
|
|
|
|
|
- if len(self.actions.items()) == 1:
|
|
|
|
|
- html += (
|
|
|
|
|
- f'<a class="btn btn-sm btn-secondary" href="{url}{url_appendix}" type="button">'
|
|
|
|
|
|
|
+ # Render a separate button if a) only one action exists, or b) if split_actions is True
|
|
|
|
|
+ if len(self.actions) == 1 or (self.split_actions and idx == 0):
|
|
|
|
|
+ dropdown_class = attrs.css_class
|
|
|
|
|
+ button = (
|
|
|
|
|
+ f'<a class="btn btn-sm btn-{attrs.css_class}" href="{url}{url_appendix}" type="button">'
|
|
|
f'<i class="mdi mdi-{attrs.icon}"></i></a>'
|
|
f'<i class="mdi mdi-{attrs.icon}"></i></a>'
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- # Creates split button for the first action with direct link and icon
|
|
|
|
|
- elif self.split_actions and idx == 0:
|
|
|
|
|
- html += (
|
|
|
|
|
- f'<span class="btn-group dropdown">'
|
|
|
|
|
- f'<a class="btn btn-sm btn-secondary" href="{url}{url_appendix}" type="button">'
|
|
|
|
|
- f'<i class="mdi mdi-{attrs.icon}"></i></a>'
|
|
|
|
|
- )
|
|
|
|
|
-
|
|
|
|
|
- # Creates standard action dropdown menu items
|
|
|
|
|
|
|
+ # Add dropdown menu items
|
|
|
else:
|
|
else:
|
|
|
- links.append(
|
|
|
|
|
|
|
+ dropdown_links.append(
|
|
|
f'<li><a class="dropdown-item" href="{url}{url_appendix}">'
|
|
f'<li><a class="dropdown-item" href="{url}{url_appendix}">'
|
|
|
f'<i class="mdi mdi-{attrs.icon}"></i> {attrs.title}</a></li>'
|
|
f'<i class="mdi mdi-{attrs.icon}"></i> {attrs.title}</a></li>'
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
# Create the actions dropdown menu
|
|
# Create the actions dropdown menu
|
|
|
- if links:
|
|
|
|
|
- dropdown_icon = '' if self.split_actions else '<i class="mdi mdi-wrench"></i>'
|
|
|
|
|
- dropdown_class = '' if self.split_actions else '<span class="dropdown">'
|
|
|
|
|
|
|
+ if button and dropdown_links:
|
|
|
|
|
+ html += (
|
|
|
|
|
+ f'<span class="btn-group dropdown">'
|
|
|
|
|
+ f' {button}'
|
|
|
|
|
+ f' <a class="btn btn-sm btn-{dropdown_class} dropdown-toggle" type="button" data-bs-toggle="dropdown" style="padding-left: 2px">'
|
|
|
|
|
+ f' <span class="visually-hidden">Toggle Dropdown</span></a>'
|
|
|
|
|
+ f' <ul class="dropdown-menu">{"".join(dropdown_links)}</ul>'
|
|
|
|
|
+ f'</span>'
|
|
|
|
|
+ )
|
|
|
|
|
+ elif button:
|
|
|
|
|
+ html += button
|
|
|
|
|
+ elif dropdown_links:
|
|
|
html += (
|
|
html += (
|
|
|
- f'{dropdown_class}'
|
|
|
|
|
- f'<a class="btn btn-sm btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">'
|
|
|
|
|
- f'{dropdown_icon}'
|
|
|
|
|
- f'<span class="visually-hidden">Toggle Dropdown</span></a>'
|
|
|
|
|
- f'<ul class="dropdown-menu">{"".join(links)}</ul></span>'
|
|
|
|
|
|
|
+ f'<span class="btn-group dropdown">'
|
|
|
|
|
+ f' <a class="btn btn-sm btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">'
|
|
|
|
|
+ f' <span class="visually-hidden">Toggle Dropdown</span></a>'
|
|
|
|
|
+ f' <ul class="dropdown-menu">{"".join(dropdown_links)}</ul>'
|
|
|
|
|
+ f'</span>'
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
# Render any extra buttons from template code
|
|
# Render any extra buttons from template code
|