Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions docs/actions/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,26 @@ All these actions are based on custom URLs generated for each of them. Handler f
For actions without intermediate steps, you can write all the logic inside handler directly. Request and object ID are both passed to these action handler functions, so you are free to fetch the instance from database and perform any operations with it. In the end, it is recommended to return redirect back to either detail or listing based on where the action was triggered from.

For actions with intermediate steps, it is recommended to use handler function only to redirect to custom URL with custom view. This view can be extended from base Unfold view, to have unified experience.


## Hide built-in actions

By default, Django and third-party packages add their own actions, which are displayed alongside any custom actions you define. In some situations, you may want to completely hide these built-in actions, this can help save horizontal space, use different icons or texts, or move actions into a dropdown menu for a cleaner interface. To hide these default actions, set `actions_list_hide_default` or `actions_detail_hide_default` to `True`.

```python
from django.utils.translation import gettext_lazy as _
from django.shortcuts import redirect

from unfold.admin import ModelAdmin
from unfold.decorators import action


class MyAdmin(ModelAdmin):
actions_list = ["my_action", "existing_action_wrapper"]
actions_list_hide_default = True

@action(description=_("History"), icon="history")
def existing_action_wrapper(self, *args, **kwargs):
# Redirect to the page URL which is created by third-party package
return redirect("https://example.com")
```
4 changes: 4 additions & 0 deletions src/unfold/mixins/action_model_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ class ActionModelAdminMixin:
"""

actions_list = () # Displayed in changelist at the top
actions_list_hide_default = False
actions_row = () # Displayed in changelist for each row in the table
actions_detail = () # Displayed in changeform at the top
actions_detail_hide_default = False
actions_submit_line = () # Displayed in changeform in the submit line (form buttons)

def changelist_view(
Expand Down Expand Up @@ -51,6 +53,7 @@ def changelist_view(

extra_context.update(
{
"actions_list_hide_default": self.actions_list_hide_default,
"actions_list": actions_list,
"actions_row": actions_row,
}
Expand Down Expand Up @@ -85,6 +88,7 @@ def changeform_view(

extra_context.update(
{
"actions_detail_hide_default": self.actions_detail_hide_default,
"actions_submit_line": actions_submit_line,
"actions_detail": actions_detail,
}
Expand Down
12 changes: 7 additions & 5 deletions src/unfold/templates/unfold/helpers/tab_actions.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
{% if actions_list or actions_detail or actions_items or nav_global %}
<ul class="flex flex-col font-medium mb-4 ml-auto mt-2 md:flex-row md:mb-0 md:mt-0 max-md:w-full">
{% if actions_items %}
{{ actions_items }}
{% endif %}
{% if not actions_list_hide_default and not actions_detail_hide_default %}
{% if actions_items %}
{{ actions_items }}
{% endif %}

{% if nav_global %}
{{ nav_global }}
{% if nav_global %}
{{ nav_global }}
{% endif %}
{% endif %}

{% for action in actions_list %}
Expand Down
2 changes: 2 additions & 0 deletions src/unfold/templatetags/unfold.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ def tab_list(context: RequestContext, page: str, opts: Options | None = None) ->
data = {
"nav_global": context.get("nav_global"),
"actions_detail": context.get("actions_detail"),
"actions_detail_hide_default": context.get("actions_detail_hide_default"),
"actions_list": context.get("actions_list"),
"actions_list_hide_default": context.get("actions_list_hide_default"),
"actions_items": context.get("actions_items"),
"is_popup": context.get("is_popup"),
"tabs_list": _get_tabs_list(context, page, opts),
Expand Down