Просмотр исходного кода

Split PanelAction into a base class and LinkAction; CopyContent should inherit from base class

Jeremy Stretch 3 месяцев назад
Родитель
Сommit
dfb08ff521
3 измененных файлов с 73 добавлено и 31 удалено
  1. 2 2
      netbox/extras/ui/panels.py
  2. 70 28
      netbox/netbox/ui/actions.py
  3. 1 1
      netbox/netbox/ui/panels.py

+ 2 - 2
netbox/extras/ui/panels.py

@@ -10,7 +10,7 @@ __all__ = (
 )
 
 
-class CustomFieldsPanel(panels.Panel):
+class CustomFieldsPanel(panels.ObjectPanel):
     template_name = 'ui/panels/custom_fields.html'
     title = _('Custom Fields')
 
@@ -39,7 +39,7 @@ class ImageAttachmentsPanel(panels.ObjectsTablePanel):
         super().__init__('extras.imageattachment', **kwargs)
 
 
-class TagsPanel(panels.Panel):
+class TagsPanel(panels.ObjectPanel):
     template_name = 'ui/panels/tags.html'
     title = _('Tags')
 

+ 70 - 28
netbox/netbox/ui/actions.py

@@ -25,13 +25,63 @@ class PanelAction:
         button_class: Bootstrap CSS class for the button
         button_icon: Name of the button's MDI icon
     """
-    template_name = 'ui/actions/link.html'
+    template_name = None
     label = None
     button_class = 'primary'
     button_icon = None
 
-    # TODO: Refactor URL parameters to AddObject
-    def __init__(self, view_name, view_kwargs=None, url_params=None, permissions=None, label=None):
+    def __init__(self, label=None, permissions=None):
+        """
+        Initialize a new PanelAction.
+
+        Parameters:
+            label: The human-friendly button text
+            permissions: A list of permissions required to display the action
+        """
+        if label is not None:
+            self.label = label
+        self.permissions = permissions
+
+    def get_context(self, context):
+        """
+        Return the template context used to render the action element.
+
+        Parameters:
+            context: The template context
+        """
+        return {
+            'label': self.label,
+            'button_class': self.button_class,
+            'button_icon': self.button_icon,
+        }
+
+    def render(self, context):
+        """
+        Render the action as HTML.
+
+        Parameters:
+            context: The template context
+        """
+        # Enforce permissions
+        user = context['request'].user
+        if not user.has_perms(self.permissions):
+            return ''
+
+        return render_to_string(self.template_name, self.get_context(context))
+
+
+class LinkAction(PanelAction):
+    """
+    A hyperlink (typically a button) within a panel to perform some associated action, such as adding an object.
+
+    Attributes:
+        label: The default human-friendly button text
+        button_class: Bootstrap CSS class for the button
+        button_icon: Name of the button's MDI icon
+    """
+    template_name = 'ui/actions/link.html'
+
+    def __init__(self, view_name, view_kwargs=None, url_params=None, **kwargs):
         """
         Initialize a new PanelAction.
 
@@ -42,12 +92,11 @@ class PanelAction:
             permissions: A list of permissions required to display the action
             label: The human-friendly button text
         """
+        super().__init__(**kwargs)
+
         self.view_name = view_name
         self.view_kwargs = view_kwargs or {}
         self.url_params = url_params or {}
-        self.permissions = permissions
-        if label is not None:
-            self.label = label
 
     def get_url(self, context):
         """
@@ -68,27 +117,14 @@ class PanelAction:
             url = f'{url}?{urlencode(url_params)}'
         return url
 
-    def render(self, context):
-        """
-        Render the action as HTML.
-
-        Parameters:
-            context: The template context
-        """
-        # Enforce permissions
-        user = context['request'].user
-        if not user.has_perms(self.permissions):
-            return ''
-
-        return render_to_string(self.template_name, {
+    def get_context(self, context):
+        return {
+            **super().get_context(context),
             'url': self.get_url(context),
-            'label': self.label,
-            'button_class': self.button_class,
-            'button_icon': self.button_icon,
-        })
+        }
 
 
-class AddObject(PanelAction):
+class AddObject(LinkAction):
     """
     An action to add a new object.
     """
@@ -112,22 +148,28 @@ class AddObject(PanelAction):
             raise ValueError(f"Invalid model label: {model}")
         view_name = get_viewname(model, 'add')
 
-        super().__init__(view_name=view_name, label=label, url_params=url_params)
+        super().__init__(view_name=view_name, url_params=url_params, label=label)
 
         # Require "add" permission on the model
         self.permissions = [get_permission_for_model(model, 'add')]
 
 
-class CopyContent:
+class CopyContent(PanelAction):
     """
     An action to copy the contents of a panel to the clipboard.
     """
     template_name = 'ui/actions/copy_content.html'
     label = _('Copy')
-    button_class = 'primary'
     button_icon = 'content-copy'
 
-    def __init__(self, target_id):
+    def __init__(self, target_id, **kwargs):
+        """
+        Instantiate a new CopyContent action.
+
+        Parameters:
+            target_id: The ID of the target element containing the content to be copied
+        """
+        super().__init__(**kwargs)
         self.target_id = target_id
 
     def render(self, context):

+ 1 - 1
netbox/netbox/ui/panels.py

@@ -54,7 +54,7 @@ class Panel(ABC):
         """
         if title is not None:
             self.title = title
-        self.actions = actions or []
+        self.actions = actions or self.actions or []
 
     def get_context(self, context):
         """