mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-26 09:16:10 -06:00
Define a default dashboard
This commit is contained in:
parent
029d22e495
commit
0bfd986f08
@ -5,4 +5,4 @@ class ExtrasConfig(AppConfig):
|
|||||||
name = "extras"
|
name = "extras"
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from . import lookups, search, signals
|
from . import dashboard, lookups, search, signals
|
||||||
|
@ -1,2 +1,47 @@
|
|||||||
# Webhook content types
|
# Webhook content types
|
||||||
HTTP_CONTENT_TYPE_JSON = 'application/json'
|
HTTP_CONTENT_TYPE_JSON = 'application/json'
|
||||||
|
|
||||||
|
# Dashboard
|
||||||
|
DEFAULT_DASHBOARD = [
|
||||||
|
{
|
||||||
|
'widget': 'extras.ObjectCountsWidget',
|
||||||
|
'width': 4,
|
||||||
|
'height': 3,
|
||||||
|
'config': {
|
||||||
|
'title': 'IPAM',
|
||||||
|
'models': [
|
||||||
|
'ipam.Aggregate',
|
||||||
|
'ipam.Prefix',
|
||||||
|
'ipam.IPRange',
|
||||||
|
'ipam.IPAddress',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'widget': 'extras.ObjectCountsWidget',
|
||||||
|
'width': 4,
|
||||||
|
'height': 3,
|
||||||
|
'config': {
|
||||||
|
'title': 'DCIM',
|
||||||
|
'models': [
|
||||||
|
'dcim.Site',
|
||||||
|
'dcim.Rack',
|
||||||
|
'dcim.Device',
|
||||||
|
'dcim.Cable',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'widget': 'extras.StaticContentWidget',
|
||||||
|
'width': 4,
|
||||||
|
'height': 3,
|
||||||
|
'config': {
|
||||||
|
'content': 'Welcome to NetBox!'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'widget': 'extras.ChangeLogWidget',
|
||||||
|
'width': 12,
|
||||||
|
'height': 6,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
2
netbox/extras/dashboard/__init__.py
Normal file
2
netbox/extras/dashboard/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from .utils import *
|
||||||
|
from .widgets import *
|
66
netbox/extras/dashboard/utils.py
Normal file
66
netbox/extras/dashboard/utils.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import uuid
|
||||||
|
|
||||||
|
from netbox.registry import registry
|
||||||
|
from extras.constants import DEFAULT_DASHBOARD
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
'get_dashboard',
|
||||||
|
'register_widget',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def register_widget(cls):
|
||||||
|
"""
|
||||||
|
Decorator for registering a DashboardWidget class.
|
||||||
|
"""
|
||||||
|
app_label = cls.__module__.split('.', maxsplit=1)[0]
|
||||||
|
label = f'{app_label}.{cls.__name__}'
|
||||||
|
registry['widgets'][label] = cls
|
||||||
|
|
||||||
|
return cls
|
||||||
|
|
||||||
|
|
||||||
|
def get_dashboard(user):
|
||||||
|
"""
|
||||||
|
Return the dashboard layout for a given User.
|
||||||
|
"""
|
||||||
|
if not user.is_anonymous and user.config.get('dashboard'):
|
||||||
|
config = user.config.get('dashboard')
|
||||||
|
else:
|
||||||
|
config = get_default_dashboard_config()
|
||||||
|
print(config)
|
||||||
|
if not user.is_anonymous:
|
||||||
|
user.config.set('dashboard', config, commit=True)
|
||||||
|
|
||||||
|
widgets = []
|
||||||
|
for grid_item in config['layout']:
|
||||||
|
widget_id = grid_item['id']
|
||||||
|
widget_config = config['widgets'][widget_id]
|
||||||
|
widget_class = registry['widgets'].get(widget_config.pop('class'))
|
||||||
|
widget = widget_class(id=widget_id, **widget_config)
|
||||||
|
widget.set_layout(grid_item)
|
||||||
|
widgets.append(widget)
|
||||||
|
|
||||||
|
return widgets
|
||||||
|
|
||||||
|
|
||||||
|
def get_default_dashboard_config():
|
||||||
|
config = {
|
||||||
|
'layout': [],
|
||||||
|
'widgets': {},
|
||||||
|
}
|
||||||
|
for widget in DEFAULT_DASHBOARD:
|
||||||
|
id = str(uuid.uuid4())
|
||||||
|
config['layout'].append({
|
||||||
|
'id': id,
|
||||||
|
'w': widget['width'],
|
||||||
|
'h': widget['height'],
|
||||||
|
'x': widget.get('x'),
|
||||||
|
'y': widget.get('y'),
|
||||||
|
})
|
||||||
|
config['widgets'][id] = {
|
||||||
|
'class': widget['widget'],
|
||||||
|
'config': widget.get('config', {}),
|
||||||
|
}
|
||||||
|
|
||||||
|
return config
|
@ -4,28 +4,16 @@ from django.contrib.contenttypes.models import ContentType
|
|||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from netbox.registry import registry
|
from .utils import register_widget
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ChangeLogWidget',
|
'ChangeLogWidget',
|
||||||
'DashboardWidget',
|
'DashboardWidget',
|
||||||
'ObjectCountsWidget',
|
'ObjectCountsWidget',
|
||||||
'StaticContentWidget',
|
'StaticContentWidget',
|
||||||
'register_widget',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def register_widget(cls):
|
|
||||||
"""
|
|
||||||
Decorator for registering a DashboardWidget class.
|
|
||||||
"""
|
|
||||||
label = f'{cls.__module__}.{cls.__name__}'
|
|
||||||
registry['widgets'][label] = cls
|
|
||||||
|
|
||||||
return cls
|
|
||||||
|
|
||||||
|
|
||||||
class DashboardWidget:
|
class DashboardWidget:
|
||||||
width = 4
|
width = 4
|
||||||
height = 3
|
height = 3
|
||||||
@ -41,6 +29,12 @@ class DashboardWidget:
|
|||||||
self.height = height
|
self.height = height
|
||||||
self.x, self.y = x, y
|
self.x, self.y = x, y
|
||||||
|
|
||||||
|
def set_layout(self, grid_item):
|
||||||
|
self.width = grid_item['w']
|
||||||
|
self.height = grid_item['h']
|
||||||
|
self.x = grid_item.get('x')
|
||||||
|
self.y = grid_item.get('y')
|
||||||
|
|
||||||
def render(self, request):
|
def render(self, request):
|
||||||
raise NotImplementedError("DashboardWidget subclasses must define a render() method.")
|
raise NotImplementedError("DashboardWidget subclasses must define a render() method.")
|
||||||
|
|
@ -9,7 +9,7 @@ from django.views.generic import View
|
|||||||
from django_tables2 import RequestConfig
|
from django_tables2 import RequestConfig
|
||||||
from packaging import version
|
from packaging import version
|
||||||
|
|
||||||
from extras import dashboard
|
from extras.dashboard.utils import get_dashboard
|
||||||
from netbox.forms import SearchForm
|
from netbox.forms import SearchForm
|
||||||
from netbox.registry import registry
|
from netbox.registry import registry
|
||||||
from netbox.search import LookupTypes
|
from netbox.search import LookupTypes
|
||||||
@ -34,19 +34,7 @@ class HomeView(View):
|
|||||||
return redirect('login')
|
return redirect('login')
|
||||||
|
|
||||||
# Build custom dashboard from user's config
|
# Build custom dashboard from user's config
|
||||||
widgets = []
|
widgets = get_dashboard(request.user)
|
||||||
for grid_item in request.user.config.get('dashboard.layout'):
|
|
||||||
config = request.user.config.get(f"dashboard.widgets.{grid_item['id']}")
|
|
||||||
widget_class = registry['widgets'].get(config.pop('class'))
|
|
||||||
widget = widget_class(
|
|
||||||
id=grid_item.get('id'),
|
|
||||||
width=grid_item['w'],
|
|
||||||
height=grid_item['h'],
|
|
||||||
x=grid_item['x'],
|
|
||||||
y=grid_item['y'],
|
|
||||||
**config
|
|
||||||
)
|
|
||||||
widgets.append(widget)
|
|
||||||
|
|
||||||
# Check whether a new release is available. (Only for staff/superusers.)
|
# Check whether a new release is available. (Only for staff/superusers.)
|
||||||
new_release = None
|
new_release = None
|
||||||
|
Loading…
Reference in New Issue
Block a user