Source code for superdjango.ui.options.actions

"""

Actions represent activities within a user interface, typically with regard to a model. This module defines the standard
actions supported by SuperDjango UI.

"""
__author__ = "Shawn Davis <shawn@superdjango.com>"
__maintainer__ = "Shawn Davis <shawn@superdjango.com>"
__version__ = "0.8.0-d"

# Imports

from django.utils.translation import gettext_lazy as _
from superdjango.ui.constants import VERB
from superdjango.ui.runtime.actions import Action

# Exports

__all__ = (
    "AjaxCreateAction",
    "AjaxDeleteAction",
    "AjaxDetailAction",
    "AjaxMarkCompleteAction",
    "AjaxUpdateAction",
    "BaseAction",
    "BaseBulkAction",
    "BatchChangeAction",
    "BulkCompareAction",
    "BulkDeleteAction",
    "BulkEditAction",
    "BulkTrashAction",
    "CreateAction",
    "DashboardAction",
    "DeleteAction",
    "DetailAction",
    "DividerAction",
    "DuplicateAction",
    "ListAction",
    "MarkArchivedAction",
    "MarkCompleteAction",
    "MarkPublishedAction",
    "MarkReviewedAction",
    "MarkResolvedAction",
    "SearchAction",
    "TrashAction",
    "UpdateAction",
)

# Base Classes


[docs]class BaseAction(object): """Base class for model "actions".""" icon = None is_ajax = False is_divider = False label = None verb = None target = None def __repr__(self): return "<%s>" % self.__class__.__name__
[docs] def as_runtime(self, request, ui, next_url=None, record=None): """Load the action. :param request: The current HTTP request instance. :param ui: The model UI instance. :type ui: ModelUI :param next_url: The value of the ``next_url``, especially on form submit. :type next_url: str :param record: The current model instance, if any. :rtype: Action | None :returns: If the pattern exists and a URL is available, an Action instance is returned. Otherwise ``None`` is returned. """ pattern = ui.get_pattern(self.verb) if pattern is None: return None url = pattern.reverse(record=record) if url is None: return None if next_url is not None: if "?" in url: url += "&next=%s" % next_url else: url += "?next=%s" % next_url kwargs = { 'icon': self.icon, 'is_ajax': self.is_ajax, 'target': self.target, } return Action(self.label, url, self.verb, **kwargs)
[docs]class BaseBulkAction(BaseAction): """Base class for bulk actions.""" select_items_message = _("Please select one or more items.")
[docs] def as_runtime(self, request, ui, next_url=None, queryset=None): """Load the bulk action. :param request: The current HTTP request instance. :param ui: The model UI instance. :type ui: ModelUI :param next_url: The value of the ``next_url``, especially on form submit. :type next_url: str :param queryset: The current queryset instance, if any. :rtype: Action | None :returns: If the pattern exists and a URL is available, an Action instance is returned. Otherwise ``None`` is returned. .. note:: The ``queryset`` parameter is not used by default. """ pattern = ui.get_pattern(self.verb) if pattern is None: return None url = pattern.reverse() if url is None: return None if next_url is not None: if "?" in url: url += "&next=%s" % next_url else: url += "?next=%s" % next_url return Action(self.label, url, self.verb, icon=self.icon)
# Classes
[docs]class BatchChangeAction(BaseBulkAction): """Definition of the batch change action.""" icon = "fas fa-edit" label = _("Change Selected Items") verb = VERB.BATCH_CHANGE
[docs]class BulkCompareAction(BaseBulkAction): """Definition of the bulk compare action.""" icon = "fas fa-th-list" label = _("Compare Selected Items") verb = VERB.BULK_COMPARE
[docs]class BulkDeleteAction(BaseBulkAction): """Definition of the bulk delete action.""" icon = "fas fa-trash-alt" label = _("Delete Selected Items") verb = VERB.BULK_DELETE
[docs]class BulkEditAction(BaseBulkAction): """Definition of the bulk edit action.""" icon = "fas fa-edit-alt" label = _("Edit") verb = VERB.BULK_EDIT
[docs]class BulkTrashAction(BaseBulkAction): """Definition of the bulk trash action.""" icon = "fas fa-trash-alt" label = _("Move Selected Items to Trash") verb = VERB.BULK_TRASH
[docs]class CreateAction(BaseAction): """Definition of the create action.""" icon = "fas fa-plus-square" label = _("Create") verb = VERB.CREATE
[docs]class DashboardAction(BaseAction): """Definition of the dashboard action.""" icon = "fas fa-tachometer-alt" label = _("Dashboard") verb = VERB.DASHBOARD
[docs] def as_runtime(self, request, ui, next_url=None, record=None): """Override to ignore next URL.""" pattern = ui.get_pattern(self.verb) if pattern is None: return None url = pattern.reverse() if url is None: return None return Action(self.label, url, self.verb, icon=self.icon)
[docs]class DeleteAction(BaseAction): """Definition of the delete action.""" icon = "fas fa-trash" label = _("Delete") verb = VERB.DELETE
[docs]class DetailAction(BaseAction): """Definition of the detail action.""" icon = "fas fa-info-circle" label = _("Detail") verb = VERB.DETAIL
[docs]class DividerAction(BaseAction): """A fake action that may be used to add a divider to a model actions menu. .. code-block:: python class TodoUI(ui.ModelUI): # ... list_options = ui.ListOptions( # ... actions=["create", "dashboard", "divider", "search", "divider"], ) """ is_divider = True
[docs] def as_runtime(self, request, ui, next_url=None, record=None): """The divider action has no pattern or URL.""" action = Action("", "", "") action.is_divider = True return action
[docs]class DuplicateAction(BaseAction): """Definition of the duplicate action.""" icon = "far fa-clone" label = _("Duplicate") verb = VERB.DUPLICATE
[docs]class ListAction(BaseAction): """Definition of the create action.""" icon = "fas fa-table" label = _("List") verb = VERB.LIST
[docs] def as_runtime(self, request, ui, next_url=None, record=None): """List action never responds to specific record instance.""" pattern = ui.get_pattern(self.verb) if pattern is None: return None # Don't use record because the pattern won't reverse. url = pattern.reverse() if url is None: return None return Action(self.label, url, self.verb, icon=self.icon)
[docs]class MarkArchivedAction(BaseAction): """Provides support for ArchivedByModel.""" icon = "fas fa-archive" label = _("Archive") verb = VERB.MARK_ARCHIVED
[docs] def as_runtime(self, request, ui, next_url=None, record=None): """A record must exist and be archived.""" if record is None: return None if record.is_archived: return None return super().as_runtime(request, ui, next_url=next_url, record=record)
[docs]class MarkCompleteAction(BaseAction): """Provides support for CompletedByModel.""" icon = "fas fa-check-square" label = _("Mark Complete") verb = VERB.MARK_COMPLETE
[docs] def as_runtime(self, request, ui, next_url=None, record=None): """A record must exist and be completed.""" if record is None: return None if record.is_complete: return None return super().as_runtime(request, ui, next_url=next_url, record=record)
[docs]class MarkPublishedAction(BaseAction): """Provides support for PublishedByModel.""" icon = "fas fa-upload" label = _("Mark Published") verb = VERB.MARK_PUBLISHED
[docs] def as_runtime(self, request, ui, next_url=None, record=None): """A record must exist and be published.""" if record is None: return None if record.is_published: return None return super().as_runtime(request, ui, next_url=next_url, record=record)
[docs]class MarkResolvedAction(BaseAction): """Provides support for ReviewedByModel.""" icon = "fas fa-door-closed" label = _("Mark Resolved") verb = VERB.MARK_RESOLVED
[docs] def as_runtime(self, request, ui, next_url=None, record=None): """A record must exist and be resolved.""" if record is None: return None if record.is_resolved: return None return super().as_runtime(request, ui, next_url=next_url, record=record)
[docs]class MarkReviewedAction(BaseAction): """Provides support for ReviewedByModel.""" icon = "far fa-eye" label = _("Mark Reviewed") verb = VERB.MARK_REVIEWED
[docs] def as_runtime(self, request, ui, next_url=None, record=None): """A record must exist and be unreviewed.""" if record is None: return None if record.is_reviewed: return None return super().as_runtime(request, ui, next_url=next_url, record=record)
[docs]class SearchAction(ListAction): """Definition of the search action.""" icon = "fas fa-search" label = _("Search") verb = VERB.SEARCH
[docs]class TrashAction(BaseAction): """Definition of the trash action.""" icon = "fas fa-trash-alt" label = _("Move to Trash") verb = VERB.TRASH
[docs]class UpdateAction(BaseAction): """Definition of the update action.""" icon = "fas fa-edit" label = _("Update") verb = VERB.UPDATE
# AJAX Classes
[docs]class AjaxCreateAction(CreateAction): """Definition of the AJAX create action.""" is_ajax = True verb = VERB.AJAX_CREATE
[docs]class AjaxDeleteAction(DeleteAction): """Definition of the AJAX delete action.""" is_ajax = True verb = VERB.AJAX_DELETE
[docs]class AjaxDetailAction(DetailAction): """Definition of the AJAX detail action.""" is_ajax = True verb = VERB.AJAX_DETAIL
[docs]class AjaxMarkCompleteAction(MarkCompleteAction): """Provides support for CompletedByModel via AJAX.""" is_ajax = True verb = VERB.AJAX_MARK_COMPLETE
[docs]class AjaxUpdateAction(UpdateAction): """Definition of the AJAX update action.""" is_ajax = True verb = VERB.AJAX_UPDATE