mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-26 09:16:10 -06:00
Clean up utility functions
This commit is contained in:
parent
892fce1518
commit
96a8c72b05
@ -1,13 +1,14 @@
|
||||
import uuid
|
||||
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
from netbox.registry import registry
|
||||
from extras.constants import DEFAULT_DASHBOARD
|
||||
from extras.models import Dashboard
|
||||
|
||||
__all__ = (
|
||||
'get_dashboard',
|
||||
'get_default_dashboard_config',
|
||||
'get_widget_class_and_config',
|
||||
'get_default_dashboard',
|
||||
'get_widget_class',
|
||||
'register_widget',
|
||||
)
|
||||
|
||||
@ -23,32 +24,36 @@ def register_widget(cls):
|
||||
return cls
|
||||
|
||||
|
||||
def get_widget_class_and_config(dashboard, id):
|
||||
config = dict(dashboard.config[id]) # Copy to avoid mutating userconfig data
|
||||
widget_class = registry['widgets'].get(config.pop('class'))
|
||||
return widget_class, config
|
||||
def get_widget_class(name):
|
||||
"""
|
||||
Return a registered DashboardWidget class identified by its name.
|
||||
"""
|
||||
try:
|
||||
return registry['widgets'][name]
|
||||
except KeyError:
|
||||
raise ValueError(f"Unregistered widget class: {name}")
|
||||
|
||||
|
||||
def get_dashboard(user):
|
||||
"""
|
||||
Return the dashboard layout for a given User.
|
||||
Return the Dashboard for a given User if one exists, or generate a default dashboard.
|
||||
"""
|
||||
if not user.is_anonymous and hasattr(user, 'dashboard'):
|
||||
dashboard = user.dashboard
|
||||
if user.is_anonymous:
|
||||
dashboard = get_default_dashboard()
|
||||
else:
|
||||
dashboard = get_default_dashboard_config()
|
||||
try:
|
||||
dashboard = user.dashboard
|
||||
except ObjectDoesNotExist:
|
||||
# Create a dashboard for this user
|
||||
dashboard = get_default_dashboard()
|
||||
dashboard.user = user
|
||||
dashboard.save()
|
||||
|
||||
widgets = []
|
||||
for grid_item in dashboard.layout:
|
||||
widget_class, widget_config = get_widget_class_and_config(dashboard, grid_item['id'])
|
||||
widget = widget_class(id=grid_item['id'], **widget_config)
|
||||
widget.set_layout(grid_item)
|
||||
widgets.append(widget)
|
||||
|
||||
return widgets
|
||||
return dashboard
|
||||
|
||||
|
||||
def get_default_dashboard_config():
|
||||
def get_default_dashboard():
|
||||
from extras.models import Dashboard
|
||||
dashboard = Dashboard(
|
||||
layout=[],
|
||||
config={}
|
||||
|
@ -61,6 +61,14 @@ class DashboardWidget:
|
||||
def name(self):
|
||||
return f'{self.__class__.__module__.split(".")[0]}.{self.__class__.__name__}'
|
||||
|
||||
@property
|
||||
def form_data(self):
|
||||
return {
|
||||
'title': self.title,
|
||||
'color': self.color,
|
||||
'config': self.config,
|
||||
}
|
||||
|
||||
|
||||
@register_widget
|
||||
class NoteWidget(DashboardWidget):
|
||||
|
@ -1,6 +1,8 @@
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db import models
|
||||
|
||||
from extras.dashboard.utils import get_widget_class
|
||||
|
||||
__all__ = (
|
||||
'Dashboard',
|
||||
)
|
||||
@ -18,7 +20,30 @@ class Dashboard(models.Model):
|
||||
class Meta:
|
||||
pass
|
||||
|
||||
def get_widget(self, id):
|
||||
"""
|
||||
Instantiate and return a widget by its ID
|
||||
"""
|
||||
id = str(id)
|
||||
config = dict(self.config[id]) # Copy to avoid mutating instance data
|
||||
widget_class = get_widget_class(config.pop('class'))
|
||||
return widget_class(id=id, **config)
|
||||
|
||||
def get_layout(self):
|
||||
"""
|
||||
Return the dashboard's configured layout, suitable for rendering with gridstack.js.
|
||||
"""
|
||||
widgets = []
|
||||
for grid_item in self.layout:
|
||||
widget = self.get_widget(grid_item['id'])
|
||||
widget.set_layout(grid_item)
|
||||
widgets.append(widget)
|
||||
return widgets
|
||||
|
||||
def add_widget(self, widget, x=None, y=None):
|
||||
"""
|
||||
Add a widget to the dashboard, optionally specifying its X & Y coordinates.
|
||||
"""
|
||||
id = str(widget.id)
|
||||
self.config[id] = {
|
||||
'class': widget.name,
|
||||
@ -35,6 +60,10 @@ class Dashboard(models.Model):
|
||||
})
|
||||
|
||||
def delete_widget(self, id):
|
||||
"""
|
||||
Delete a widget from the dashboard.
|
||||
"""
|
||||
id = str(id)
|
||||
del self.config[id]
|
||||
self.layout = [
|
||||
item for item in self.layout if item['id'] != id
|
||||
|
@ -10,7 +10,6 @@ from django_rq.queues import get_connection
|
||||
from rq import Worker
|
||||
|
||||
from extras.dashboard.forms import DashboardWidgetAddForm, DashboardWidgetForm
|
||||
from extras.dashboard.utils import get_widget_class_and_config
|
||||
from netbox.registry import registry
|
||||
from netbox.views import generic
|
||||
from utilities.forms import ConfirmationForm, get_field_value
|
||||
@ -725,10 +724,9 @@ class DashboardWidgetConfigView(LoginRequiredMixin, View):
|
||||
template_name = 'extras/dashboard/widget_config.html'
|
||||
|
||||
def get(self, request, id):
|
||||
id = str(id)
|
||||
widget_class, config = get_widget_class_and_config(request.user.dashboard, id)
|
||||
widget_form = DashboardWidgetForm(initial=config)
|
||||
config_form = widget_class.ConfigForm(initial=config.get('config'), prefix='config')
|
||||
widget = request.user.dashboard.get_widget(id)
|
||||
widget_form = DashboardWidgetForm(initial=widget.form_data)
|
||||
config_form = widget.ConfigForm(initial=widget.form_data.get('config'), prefix='config')
|
||||
|
||||
if not is_htmx(request):
|
||||
return redirect('home')
|
||||
@ -740,15 +738,16 @@ class DashboardWidgetConfigView(LoginRequiredMixin, View):
|
||||
})
|
||||
|
||||
def post(self, request, id):
|
||||
id = str(id)
|
||||
widget_class, config = get_widget_class_and_config(request.user.dashboard, id)
|
||||
widget = request.user.dashboard.get_widget(id)
|
||||
widget_form = DashboardWidgetForm(request.POST)
|
||||
config_form = widget_class.ConfigForm(request.POST, prefix='config')
|
||||
config_form = widget.ConfigForm(request.POST, prefix='config')
|
||||
|
||||
if widget_form.is_valid() and config_form.is_valid():
|
||||
data = widget_form.cleaned_data
|
||||
data['config'] = config_form.cleaned_data
|
||||
request.user.dashboard.config[id].update(data)
|
||||
print(request.user.dashboard.config)
|
||||
print(data)
|
||||
request.user.dashboard.config[str(id)].update(data)
|
||||
request.user.dashboard.save()
|
||||
|
||||
response = HttpResponse()
|
||||
@ -766,15 +765,13 @@ class DashboardWidgetDeleteView(LoginRequiredMixin, View):
|
||||
template_name = 'generic/object_delete.html'
|
||||
|
||||
def get(self, request, id):
|
||||
id = str(id)
|
||||
widget_class, config = get_widget_class_and_config(request.user.dashboard, id)
|
||||
widget = widget_class(**config)
|
||||
widget = request.user.dashboard.get_widget(id)
|
||||
form = ConfirmationForm(initial=request.GET)
|
||||
|
||||
# If this is an HTMX request, return only the rendered deletion form as modal content
|
||||
if is_htmx(request):
|
||||
return render(request, 'htmx/delete_form.html', {
|
||||
'object_type': widget_class.__name__,
|
||||
'object_type': widget.__class__.__name__,
|
||||
'object': widget,
|
||||
'form': form,
|
||||
'form_url': reverse('extras:dashboardwidget_delete', kwargs={'id': id})
|
||||
@ -785,7 +782,6 @@ class DashboardWidgetDeleteView(LoginRequiredMixin, View):
|
||||
})
|
||||
|
||||
def post(self, request, id):
|
||||
id = str(id)
|
||||
form = ConfirmationForm(request.POST)
|
||||
|
||||
if form.is_valid():
|
||||
|
@ -32,8 +32,8 @@ class HomeView(View):
|
||||
if settings.LOGIN_REQUIRED and not request.user.is_authenticated:
|
||||
return redirect('login')
|
||||
|
||||
# Build custom dashboard from user's config
|
||||
widgets = get_dashboard(request.user)
|
||||
# Construct the user's custom dashboard layout
|
||||
dashboard = get_dashboard(request.user).get_layout()
|
||||
|
||||
# Check whether a new release is available. (Only for staff/superusers.)
|
||||
new_release = None
|
||||
@ -48,7 +48,7 @@ class HomeView(View):
|
||||
}
|
||||
|
||||
return render(request, self.template_name, {
|
||||
'widgets': widgets,
|
||||
'dashboard': dashboard,
|
||||
'new_release': new_release,
|
||||
})
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
{% block content-wrapper %}
|
||||
{# Render the user's customized dashboard #}
|
||||
<div class="grid-stack">
|
||||
{% for widget in widgets %}
|
||||
{% for widget in dashboard %}
|
||||
{% include 'extras/dashboard/widget.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user