1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #12107: Document support for plugin-provided dashboard widgets

This commit is contained in:
jeremystretch
2023-04-03 14:15:18 -04:00
parent 872b70c2b5
commit 0676ed45c7
3 changed files with 78 additions and 6 deletions

View File

@ -0,0 +1,52 @@
# Dashboard Widgets
!!! note "Introduced in v3.5"
Support for custom dashboard widgets was introduced in NetBox v3.5.
Each NetBox user can customize his or her personal dashboard by adding and removing widgets and by manipulating the size and position of each. Plugins can register their own dashboard widgets to complement those already available natively.
## The DashboardWidget Class
All dashboard widgets must inherit from NetBox's `DashboardWidget` base class. Subclasses must provide a `render()` method, and may override the base class' default characteristics.
Widgets which require configuration by a user must also include a `ConfigForm` child class. This form is used to render the user configuration options for the widget.
::: extras.dashboard.widgets.DashboardWidget
## Widget Registration
To register a dashboard widget for use in NetBox, import the `register_widget()` decorator and use it to wrap each `DashboardWidget` subclass:
```python
from extras.dashboard.widgets import DashboardWidget, register_widget
@register_widget
class MyWidget1(DashboardWidget):
...
@register_widget
class MyWidget2(DashboardWidget):
...
```
## Example
```python
from django import forms
from extras.dashboard.utils import register_widget
from extras.dashboard.widgets import DashboardWidget
@register_widget
class ReminderWidget(DashboardWidget):
default_title = 'Reminder'
description = 'Add a virtual sticky note'
class ConfigForm(forms.Form):
content = forms.CharField(
widget=forms.Textarea()
)
def render(self, request):
return self.config.get('content')
```

View File

@ -137,6 +137,7 @@ nav:
- REST API: 'plugins/development/rest-api.md'
- GraphQL API: 'plugins/development/graphql-api.md'
- Background Tasks: 'plugins/development/background-tasks.md'
- Dashboard Widgets: 'plugins/development/dashboard-widgets.md'
- Staged Changes: 'plugins/development/staged-changes.md'
- Exceptions: 'plugins/development/exceptions.md'
- Administration:

View File

@ -37,13 +37,26 @@ def get_content_type_labels():
class DashboardWidget:
"""
Base class for custom dashboard widgets.
Attributes:
description: A brief, user-friendly description of the widget's function
default_title: The string to show for the widget's title when none has been specified.
default_config: Default configuration parameters, as a dictionary mapping
width: The widget's default width (1 to 12)
height: The widget's default height; the number of rows it consumes
"""
description = None
default_title = None
default_config = {}
description = None
width = 4
height = 3
class ConfigForm(forms.Form):
class ConfigForm(BootstrapMixin, forms.Form):
"""
The widget's configuration form.
"""
pass
def __init__(self, id=None, title=None, color=None, config=None, width=None, height=None, x=None, y=None):
@ -67,6 +80,12 @@ class DashboardWidget:
self.y = grid_item.get('y')
def render(self, request):
"""
This method is called to render the widget's content.
Params:
request: The current request
"""
raise NotImplementedError(f"{self.__class__} must define a render() method.")
@property
@ -87,7 +106,7 @@ class NoteWidget(DashboardWidget):
default_title = _('Note')
description = _('Display some arbitrary custom content. Markdown is supported.')
class ConfigForm(BootstrapMixin, forms.Form):
class ConfigForm(DashboardWidget.ConfigForm):
content = forms.CharField(
widget=forms.Textarea()
)
@ -102,7 +121,7 @@ class ObjectCountsWidget(DashboardWidget):
description = _('Display a set of NetBox models and the number of objects created for each type.')
template_name = 'extras/dashboard/widgets/objectcounts.html'
class ConfigForm(BootstrapMixin, forms.Form):
class ConfigForm(DashboardWidget.ConfigForm):
models = forms.MultipleChoiceField(
choices=get_content_type_labels
)
@ -132,7 +151,7 @@ class ObjectListWidget(DashboardWidget):
width = 12
height = 4
class ConfigForm(BootstrapMixin, forms.Form):
class ConfigForm(DashboardWidget.ConfigForm):
model = forms.ChoiceField(
choices=get_content_type_labels
)
@ -177,7 +196,7 @@ class RSSFeedWidget(DashboardWidget):
width = 6
height = 4
class ConfigForm(BootstrapMixin, forms.Form):
class ConfigForm(DashboardWidget.ConfigForm):
feed_url = forms.URLField(
label=_('Feed URL')
)